import path from 'path';
import fs from 'fs';
import webpack from 'webpack';
import chalk from 'chalk';
import { merge } from 'webpack-merge';
import { spawn, execSync } from 'child_process';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from '../scripts/CheckNodeEnv';
import ReactRefreshWebpackPlugin from '#pmmmwh/react-refresh-webpack-plugin';
// When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
// at the dev webpack config is not accidentally run in a production environment
if (process.env.NODE_ENV === 'production') {
CheckNodeEnv('development');
}
const port = process.env.PORT || 1212;
const publicPath = `http://localhost:${port}/dist`;
const dllDir = path.join(__dirname, '../dll');
const manifest = path.resolve(dllDir, 'renderer.json');
const requiredByDLLConfig = module.parent.filename.includes(
'webpack.config.renderer.dev.dll'
);
/**
* Warn if the DLL is not built
*/
if (!requiredByDLLConfig && !(fs.existsSync(dllDir) && fs.existsSync(manifest))) {
console.log(
chalk.black.bgYellow.bold(
'The DLL files are missing. Sit back while we build them for you with "yarn build-dll"'
)
);
execSync('yarn build-dll');
}
export default merge(baseConfig, {
devtool: 'inline-source-map',
mode: 'development',
target: 'electron-renderer',
entry: [
'core-js',
'regenerator-runtime/runtime',
require.resolve('../../src/renderer/index.tsx'),
],
output: {
publicPath: `http://localhost:${port}/dist/`,
filename: 'renderer.dev.js',
},
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('babel-loader'),
options: {
plugins: [
require.resolve('react-refresh/babel'),
].filter(Boolean),
},
},
],
},
{
test: /\.global\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
}
}
],
},
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
sourceMap: true,
importLoaders: 1,
},
},
{
loader: 'postcss-loader',
options: {
postcssOptions: {
plugins: [require('tailwindcss'), require('autoprefixer')],
},
}
}
],
},
// SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.(scss|sass)$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
},
],
},
// SASS support - compile all other .scss files and pipe it to style.css
{
test: /^((?!\.global).)*\.(scss|sass)$/,
use: [
{
loader: 'style-loader',
},
{
loader: '#teamsupercell/typings-for-css-modules-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]__[hash:base64:5]',
},
sourceMap: true,
importLoaders: 1,
},
},
{
loader: 'sass-loader',
},
],
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
},
},
},
// OTF Font
{
test: /\.otf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'font/otf',
},
},
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream',
},
},
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader',
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml',
},
},
},
// Common Image Formats
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
use: 'url-loader',
},
],
},
plugins: [
requiredByDLLConfig
? null
: new webpack.DllReferencePlugin({
context: path.join(__dirname, '../dll'),
manifest: require(manifest),
sourceType: 'var',
}),
new webpack.NoEmitOnErrorsPlugin(),
/**
* Create global constants which can be configured at compile time.
*
* Useful for allowing different behaviour between development builds and
* release builds
*
* NODE_ENV should be production so that modules do not perform certain
* development checks
*
* By default, use 'development' as NODE_ENV. This can be overriden with
* 'staging', for example, by changing the ENV variables in the npm scripts
*/
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
}),
new webpack.LoaderOptionsPlugin({
debug: true,
}),
new ReactRefreshWebpackPlugin(),
],
node: {
__dirname: false,
__filename: false,
},
devServer: {
disableHostCheck: true,
port,
publicPath,
compress: true,
noInfo: false,
stats: 'errors-only',
inline: true,
lazy: false,
hot: true,
headers: { 'Access-Control-Allow-Origin': '*' },
contentBase: path.join(__dirname, 'dist'),
watchOptions: {
aggregateTimeout: 300,
ignored: /node_modules/,
poll: 100,
},
historyApiFallback: {
verbose: true,
disableDotRule: false,
},
before() {
console.log('Starting Main Process...');
spawn('npm', ['run', 'start:main'], {
shell: true,
env: process.env,
stdio: 'inherit',
})
.on('close', (code) => process.exit(code))
.on('error', (spawnError) => console.error(spawnError));
},
},
});
I use the https://github.com/electron-react-boilerplate/electron-react-boilerplate as the template to do a electron application. After introducing tailwind css and react router, my web devserver will constantly compile like image after touching a file. Does any one has the issue and give me a help? Sorry about too many js code in webpack configuration js, but I think lots of part can be skpied.
Related
i'm facing an issue with react with custom webpack config while I try to implement firebase
react version: 17+
webpack version: 5+
firebase: 9+
so when i try to import any function from firebase/messaging (also tried other packages from firebase like analytics, same issue happens) it throws an error about exports-loader module that is not installed.
then after installation it throws this error then:
ERROR in ./node_modules/whatwg-fetch/fetch.js (./node_modules/exports-loader/dist/cjs.js?self.fetch!./node_modules/whatwg-fetch/fetch.js)
Module build failed (from ./node_modules/exports-loader/dist/cjs.js):
ValidationError: Invalid options object. Exports Loader has been initialized using an options object that does not match the API schema.
options misses the property 'exports'. Should be:
non-empty string | non-empty string | object { name, syntax?, alias? } | [non-empty string | object { name, syntax?, alias? }, ...] (should not
have fewer than 1 item)
here is my webpack config, is there anything that I'm missing from webpack config or is this issue caused by webpack at all?
module.exports = {
devtool: 'eval',
entry: ['app/app.js'],
loader: { target: 'web' },
mode: 'development',
module: {
strictExportPresence: true,
rules: [
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {
iesafe: true,
},
},
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
loader: 'babel-loader',
include: [PATHS.APP_DIR],
exclude: [/node_modules/],
options: {
...babelConfig,
},
},
{
test: /\.(eot|otf|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'fonts',
},
},
],
},
{
test: /\.(gif|png|jpe?g)$/i,
use: [
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65,
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.9],
speed: 4,
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75,
},
},
},
{
loader: 'file-loader',
options: {
name: '[name].[contenthash].[ext]',
outputPath: 'images',
},
},
],
},
{
test: /\.(s*)css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
sourceMap: true,
importLoaders: 1,
},
},
],
},
],
},
node: { global: false, __dirname: false, __filename: false },
output: {
path: 'build/',
publicPath: '/',
filename: '[name].js',
chunkFilename: '[name].chunk.js',
},
plugins: [
new WebpackBar({
name: 'CSR',
color: '#FFEB3B',
}),
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
new webpack.DefinePlugin({
'process.env': webpackEnv(),
}),
new LoadablePlugin({
filename: 'loadable-stats.json',
writeToDisk: true,
}),
new CopyPlugin({
patterns: [
{
from: path.join('resources', 'public'),
to: 'build',
},
],
}),
new HtmlWebPackPlugin({
template: `/index.ejs`,
title: 'MY APP',
}),
new webpack.HotModuleReplacementPlugin({
multiStep: false,
}),
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/, // exclude node_modules
failOnError: false, // show a warning when there is a circular dependency
}),
],
resolve: {
modules: ['node_modules'],
alias: {
// my aliases
},
},
stats: { preset: 'minimal', moduleTrace: true, errorDetails: true },
target: 'web',
};
the issue was caused by whatwg-fetch
fetch: 'exports-loader?self.fetch!whatwg-fetch',
by removing this line since it wasn't necessary, the problem has been solved
I have a fairly standard lerna monorepo setup, using yarn workspaces and TypeScript.
There are pacakge folders for various services and also the React frontend. I've been migrating the Webpack config to Webpack 5 so that I can take advantage of the module federation. The React app is complex, uses CSS modules with scss, TypeScript, etc so the config is relatively complex, nevertheless I feel as if I am there with compilation. That notwithstanding there are 2 issues that I cannot seem to fathom, the most problematic of them being that webpack seems to be trying to load files from other packages in the monorepo (and these are causing TypeScript/eslint errors).
Webpack.config.js
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const ESLintPlugin = require("eslint-webpack-plugin");
const isDevelopment = process.env.NODE_ENV === "development";
const imageInlineSizeLimit = 2000;
// Default js and ts rules
const tsRules = {
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: path.resolve(__dirname, "src"),
exclude: [/node_modules/],
loader: "babel-loader",
options: {
customize: require.resolve("babel-preset-react-app/webpack-overrides"),
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
],
plugins: [],
},
};
// Process any JS outside of the app with Babel.
// Unlike the application files, we only compile the standard ES features.
const externalJsRules = {
test: /\.(js|mjs)$/,
exclude: [/node_modules/],
loader: "babel-loader",
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve("babel-preset-react-app/dependencies"),
{ helpers: true },
],
],
cacheDirectory: true,
cacheCompression: false,
},
};
let plugins = [
new ForkTsCheckerWebpackPlugin({
async: false,
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
}),
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[id].[contenthash].css",
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public", "index.html"),
}),
new webpack.IgnorePlugin({
// #todo: this prevents webpack paying attention to all tests and stories, which probably ought only be done on build
resourceRegExp: /(coverage\/|\.spec.tsx?|\.mdx?$)/,
}),
];
if (isDevelopment) {
// For use with dev server
tsRules.options.plugins.push("react-refresh/babel");
externalJsRules.options.sourceMaps = true;
externalJsRules.options.inputSourceMap = true;
plugins = [...plugins, new webpack.HotModuleReplacementPlugin()];
}
module.exports = {
entry: path.resolve(__dirname, "src", "index.tsx"),
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/",
clean: true,
},
module: {
rules: [
externalJsRules,
tsRules,
{
test: [/\.avif$/],
loader: "url-loader",
options: {
limit: imageInlineSizeLimit,
mimetype: "image/avif",
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: "url-loader",
options: {
limit: imageInlineSizeLimit,
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: /\.svg$/,
use: ["#svgr/webpack", "url-loader"],
},
{
test: /\.s?css$/,
oneOf: [
{
test: /\.module\.s?css$/,
use: [
isDevelopment
? // insert css into DOM via js
"style-loader"
: // insert link tags
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
modules: true,
sourceMap: isDevelopment,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
},
],
"postcss-normalize",
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: isDevelopment,
},
},
],
},
{
use: [
isDevelopment
? // insert css into DOM via js
"style-loader"
: // insert link tags
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: isDevelopment,
importLoaders: 2,
},
},
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-flexbugs-fixes",
[
"postcss-preset-env",
{
autoprefixer: {
flexbox: "no-2009",
},
stage: 3,
},
],
"postcss-normalize",
],
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: isDevelopment,
},
},
],
},
],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".scss"],
symlinks: false,
// don't provide polyfills for non UUI-core
fallback: {
// crypto: false,
// fs: false,
// stream: false,
// path: false,
},
},
optimization: {
runtimeChunk: true,
},
plugins: [...plugins],
devtool: "eval-cheap-module-source-map",
devServer: {
static: path.join(__dirname, "build"),
historyApiFallback: true,
port: 3000,
open: true,
hot: true,
},
};
Webpack is run from the frontend package folder. Also I have scanned the code for any refrences to other packages in the React code, but there are none, so I can't understand why this is loading and how to prevent them loading.
Example error:
ERROR in ../../node_modules/#githubpackage/src/aFile.ts:2:25
TS2801: This condition will always return true since this 'Promise<boolean>' is always defined.
Help much appreciated (I realise the issue should be fixed too ;p).
[EDIT] I've edited the error to indicate that the problematic package is the only package that I am installing via github packages (in a couple of the other monorepo packages).
ALSO I edited the entry file so that it only imported React and ReactDOM and rendered a <p> tag and webpack still tried loading this package... so unless there is something wrong with the webpack config, this is some odd behaviour.
Below is the webpack production file
const webpack = require("webpack");
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CompressionPlugin = require("compression-webpack-plugin");
const FixStyleOnlyEntriesPlugin = require("webpack-fix-style-only-entries");
module.exports = {
mode: 'production',
watch: false,
entry: {
main : './src/client/index.js',
FilterCss: './public/css/Filter.css',
listingCss: './public/css/listingPage.css'
},
devtool:false,
node: {
fs: 'empty',
child_process: "empty"
},
output: {
path: path.join(__dirname, '/dist/'),
filename: './[name].bundle.js'
},
resolve: {
alias: {
}
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
sourceMap: true,
modules: true,
localIdentName: '[local]'
}
}]
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
'sass-loader'
]
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets:['#babel/preset-env', '#babel/preset-react']
}
},
{
test: /\.(jpe?g|png|gif)$/,
loader: 'url-loader',
options: {
// Inline files smaller than 10 kB (10240 bytes)
limit: 10 * 1024,
},
},
{
test: /\.(jpe?g|png|gif|svg)$/,
loader: 'image-webpack-loader',
// This will apply the loader before the other ones
enforce: 'pre',
},
]
},
performance: {
hints: false
},
optimization: {
// nodeEnv: 'production',
minimize: true,
// concatenateModules: true,
// runtimeChunk: true,
splitChunks: {
// chunks: 'async',
chunks:'all',
// cacheGroups: {
// common: {
// test: /[\\/]node_modules[\\/]/,
// name: "vendors",
// chunks: "all",
// },
// },
},
runtimeChunk: 'single',
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css'
}),
new FixStyleOnlyEntriesPlugin(),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
}),
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
})
]
};
server.js
var express = require('express');
let cookieParser = require('cookie-parser');
var app = express();
const compression = require('compression');
const handleRender = require('./src/server/handleRender');
app.set('view engine', 'js');
app.engine('js', reactViews.createEngine());
require("#babel/polyfill");
var device = require('express-device');
require("#babel/register");
app.use(device.capture());
app.use(cookieParser());
app.use(compression());
app.use((req, res, next) => {
res.set('Cache-Control', 'public, max-age=31557600')
next()
})
app.use(express.static(__dirname + '/public'));
app.use('/dist', express.static('dist'));
app.get('/',function(req, res,next) {
console.log('Home app.use')
handleRender(req, res, next);
});
When I use pagespeed to check the score it show 81% on desktop but when I check the score on the gtmetrix score is 38%.
For the project uses React, redux, webpack 4 and express. and follow https://github.com/william-woodhead/simple-universal-react-redux repo and https://redux.js.org/usage/server-rendering for server side rendering and implementation.
How can we increase the score in the react-redux ssr project?
I'm trying to integrate the monaco editor into an existing react application. I followed the installation steps from (react-monaco-editor), but I don't get any syntax highlighting or autocomplete for typescript, consistent with the FAQ as if I hadn't set up the monaco-editor-webpack-plugin.
I have setup the plugin though. I can see that the monaco-editor-webpack-plugin is dropping files along side my app.js, so I presume it is working:
It seems my issue is that react-monaco-editor is trying to pull these files from the wrong location. If I load my page and open my network tab, I can see the following:
There are two problems:
1 - the paths are full paths on my system but should be relative paths - e.g.
http://127.0.0.1/dist/app/secured/49.js
2 - there is a slash missing between "secured" and "49.js" (secured49.js) and also for the other numeric files, but the editor.worker.js has the slash (weird).
So the question I'm hoping to answer is - how does react-monaco-editor determine the paths it will pull these files from, and is there a way I can influence the pathing?
Any help or recommendations would be much appreciated! Some snippets of my code below in case helpful.
package.json:
"monaco-editor-webpack-plugin": "^1.7.0",
"react-monaco-editor": "^0.26.2",
weback.config.js
'use strict';
const path = require('path');
const webpack = require('webpack');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
process.noDeprecation = true;
const babel = {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
['#babel/plugin-proposal-decorators', { 'legacy': true }],
['jsx-control-statements'],
'#babel/plugin-proposal-function-bind',
['#babel/plugin-proposal-decorators', { 'legacy': true }],
['#babel/plugin-proposal-class-properties', { 'loose': true }]
],
compact: true
}
};
const config = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'app.js'
},
mode: 'development', // Change to production on checkin
context: settings.app(),
resolve: {
modules: [
settings.app(),
path.join(settings.project(), 'node_modules'),
path.join(__dirname, 'node_modules')
],
symlinks: true,
extensions: ['.js', '.jsx', '.json', '.css', 'scss', 'less']
},
resolveLoader: {
modules: [
path.join(settings.project(), 'node_modules'),
path.join(__dirname, 'node_modules')
],
symlinks: true
},
module: {
rules: [
{
test: /.(js|jsx)?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-react'
],
plugins: [
'#babel/plugin-proposal-function-bind',
['jsx-control-statements'],
['#babel/plugin-proposal-decorators', {'legacy': true}],
['#babel/plugin-proposal-class-properties', { 'loose': true }]
],
compact: true
}
}
],
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.less$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'less-loader'
}
]
},
{
test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 100000,
mimetype: 'application/font-woff'
}
}]
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 100000,
mimetype: 'application/octet-stream'
}
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 100000,
mimetype: 'application/image/svg+xml'
}
}]
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
{
test: /-font\.otf(\?.+)?$/,
use: [
'file-loader?name=fonts/[name].[ext]'
]
}
]
},
devtool: 'source-map',
node: {
console: true,
fs: 'empty',
net: 'empty',
tls: 'empty'
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
new CaseSensitivePathsPlugin(),
new MonacoWebpackPlugin()
]
};
module.exports = config;
index.js
import { observer } from 'mobx-react';
import React, { Component } from 'react';
import MonacoEditor from 'react-monaco-editor';
#observer
export default class TSEditor extends Component {
constructor(props) {
super(props);
this.state = {
code: 'var name : string = "kyle";'
};
this.editorDidMount = this.editorDidMount.bind(this);
this.onChange = this.onChange.bind(this);
}
onChange(newValue, e) {
console.log('onChange', newValue, e);
}
editorDidMount(editor, monaco) {
console.log('editorDidMount', editor);
editor.focus();
}
render() {
const code = this.state.code;
const options = {
selectOnLineNumbers: true
};
return (
<MonacoEditor
language="typescript"
theme="vs-dark"
value={code}
options={options}
onChange={this.onChange}
editorDidMount={this.editorDidMount}
/>
);
}
}
I my case... this did the trick... within webpack.config.js
devServer: {
https: true,
port: 3000,
publicPath: "/dist/"
},
...
..
.
plugins: [
...
..
.
new MonacoWebpackPlugin({
publicPath: "/dist/"
})
]
available options are documented at https://github.com/Microsoft/monaco-editor-webpack-plugin#options
This turned out to be a problem caused by an incorrect publicPath in the output portion of my webpack configuration.
For anyone else with a similar issue, add a publicPath in your webpack configuration that gives the correct location of your web worker JS files.
I'm integrating typescript in my React app which has significant amount of code. I've some app level HOCs which I apply on React Components as :
import React from 'react';
import HOC1 from 'app/hocs/hoc1';
import compose from 'recompose/compose;
class MyComponent from React.Component {
...component stuff...
}
export default compose(HOC1())(MyComponent);
But now I've added typescript in my application, whenever I'm importing
import HOC1 from 'app/hocs/hoc1';
it says
TS2307: Cannot find module 'app/hocs/hoc1'.
I don't want to add type definitions to all my HOCs. What is the solution and why I'm getting this error?
[EDIT] I'm using baseUrl in tsconfig as well. My folder structure is
/Project/configs/tsconfig
/Project/src/app/hocs
In tsconfig, I've given baseUrl as ../src through this documentation.
Another Edit
And my webpack config looks like :
{
test: /\.(t|j)sx?$/,
loader: 'happypack/loader?id=jsx-without-proptypes',
include: [
path.resolve(__dirname),
path.resolve(__dirname, '../src'),
],
},
The whole webpack config looks something like
const config = {
context: path.resolve(__dirname, '../src'),
mode: NODE_ENV,
optimization: {
splitChunks: false,
nodeEnv: NODE_ENV,
minimize: false,
},
node: {
net: 'empty',
},
output: {
path: path.resolve(__dirname, '../build/public/assets'),
publicPath: '/assets/',
sourcePrefix: ' ',
pathinfo: DEBUG, //https://webpack.js.org/configuration/output/#output-pathinfo
},
module: {
noParse: [/html2canvas/],
rules: [
{
test: /\.tsx?$/,
enforce: 'pre',
use: { loader: 'awesome-typescript-loader' },
},
...shimLoaders,
...selectiveModulesLoader,
{
test: /\.(t|j)sx?$/,
loader: 'happypack/loader?id=jsx-without-proptypes',
include: [
path.resolve(__dirname),
path.resolve(__dirname, '../src'),
],
},
{
test: /\.jsx?$/,
loader: 'happypack/loader?id=jsx-without-lodash-plugin',
include: [
path.resolve(__dirname, '../src/app/modules/insights/'),
],
exclude: /node_modules/,
},
{
test: /\.jsx?$/,
loader: 'happypack/loader?id=jsx-with-proptypes',
},
{
test: /\.jsx?$/,
loader: 'babel-loader',
query: {
presets: [['env', { include: ['babel-plugin-transform-es2015-template-literals'] }]],
},
},
{
test: /\.css$/,
use: getCssLoaders({
pwd: PWD,
debug: DEBUG,
}),
},
...getScssRules(DEBUG, PWD),
{
test: /\.less$/,
use: [DEBUG ? 'css-loader' : 'css-loader?minimize', 'less-loader'],
},
{
test: /\.txt$/,
loader: 'raw-loader',
},
{
test: /\.svg$/,
loader: 'spr-svg-loader',
},
{
test: /\.(png|jpg|jpeg|gif)$/,
loader: 'url-loader',
query: {
name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
limit: 10000,
},
},
{
test: /\.(woff|woff2)$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/font-woff',
},
{
test: /\.(otf|ttf)$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/octet-stream',
},
{
test: /\.eot$/,
loader: 'url-loader?name=fonts/[name].[ext]&limit=65000&mimetype=application/vnd.ms-fontobject',
},
{
test: /\.(wav|mp3)$/,
loader: 'file-loader',
query: {
name: DEBUG ? '[path][name].[ext]' : '[hash].[ext]', // ?[hash]
},
},
{
test: /\.pug/,
loader: 'pug-loader',
},
{
test: /\.html$/,
include: /src\/app/,
loader: StringReplacePlugin.replace({
replacements: [
{
//Replaces ES6 strings from languagePack to simple string
pattern: /__\(\s*`([^`]*)`\s*\)/gi,
replacement: (match, p1) => {
let replacedStr = p1;
replacedStr = replacedStr.replace(new RegExp('\\$\\{([\\w\\.\\:\\-]+)\\}', 'g'), '\' + $1 + \'');
return `'${replacedStr}'`;
},
},
{
//Following methods - look out carefully for the *quotes* (single/double)
//doing what i18nPlugin would do for html files - with the *single* quotes
pattern: /__\(\s*'(.+?)'\s*\)/g,
replacement: (match, p1) => {
const replacedStr = p1;
return `'${replacedStr}'`;
},
},
{
//doing what i18nPlugin would do for html files - with the *double* quotes
pattern: /__\(\s*"(.+?)"\s*\)/g,
replacement: (match, p1) => {
const replacedStr = p1;
return `"${replacedStr}"`;
},
},
],
}),
},
],
},
resolve: {
modules: [
path.resolve(PWD),
path.resolve(PWD, '..'),
'node_modules',
'web_modules',
'src',
],
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.webpack.js', '.web.js'],
alias: ALIAS,
// symlinks: false, //https://webpack.js.org/configuration/resolve/#resolve-symlinks, https://github.com/webpack/webpack/issues/1643
},
plugins: [getProvidePlugin(), getLoaderOptionPlugin({ debug: DEBUG }), ...getHappypackPlugin({ debug: DEBUG })],
resolveLoader: {
modules: ['node_modules', path.resolve(PWD, '../../node_modules'), path.resolve(PWD, './config/loaders/')],
alias: {
text: 'raw-loader', // treat text plugin as raw-loader
jst: 'ejs-loader',
style: 'style-loader',
imports: 'imports-loader',
},
},
bail: !DEBUG,
watch: DEBUG,
cache: DEBUG,
stats: DEBUG ?
{
colors: true,
reasons: false,
hash: VERBOSE,
version: VERBOSE,
timings: true,
chunks: false,
chunkModules: VERBOSE,
cached: VERBOSE,
cachedAssets: VERBOSE,
performance: true,
} :
{ all: false, assets: true, warnings: true, errors: true, errorDetails: false },
};
Another Edit
Alias as defined on webpack config also didn't do the trick.
https://webpack.js.org/configuration/resolve/#resolve-alias
Using Alias
To map the imports to the right files you'll need to use the config.resolve.alias field in the webpack configuration.
Where in your scenario will look like:
const config = {
resolve: {
alias: {
'app': path.resolve(__dirname, 'src/app/'),
},
},
};
I am not 100% sure I am doing it right, but I also specify paths key in tsconfig, like this:
"baseUrl": "./src",
"paths": {
"#common/*": ["./common/*"],
"#moduleA/*": ["./moduleA/*"],
"#moduleB/*": ["./moduleB/*"],
}
and it seems to work all right. # prefix is just something i do to discern between my modules and npm dependencies