Why is Webpack 4 runtimeChunk in all entrypoints? - node.js

I am currently upgrading WP from v1.2 => v4.1 on a large commercial application. I am having an issue where splitChunks is creating multiple instances of my store for each entry point (The store we are using is extremely old and outdated, but that is out of my control ATM).
The issue as I see it is that runtime code is being added to each entry point which executes the same module multiple times - I succeeded in recreating the issue in a sandboxed environment and when I added a single runtimeChunk to my config this extracted the runtime code into a single file and resolved my issue - however when I applied this to my application - a runtime file WAS created, but runtimeChunk remained in each entrypoint also and so the problem still persists. Below is an example of my current config.
module.exports = {
entry: {
app: [
'babel-polyfill',
'whatwg-fetch',
'./src/app/app'
],
testEntry: './src/modules/testEntry.js',
},
output: {
pathinfo: true,
publicPath: '/',
chunkFilename: '[id].js'
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
]
},
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
filename: "js/[name].js",
test: /\.js(x)?$/,
chunks: "initial",
minChunks: 1
}
}
},
runtimeChunk: {
name: 'shared',
},
},
mode: 'development',
devtool: 'eval',
devServer: {
contentBase: __dirname,
port: 5000
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};
Is another way I can force runtime code to be executed only once?
EDITED UPDATE
I have now updated to webpack 4.17 (latest) and now oddly - when I use the single runtime option - my entry bundles are not generated

Related

webpack 5 maxing out on RAM when bundling for karma tests

I recently updated webpack to version 5, and now when compiling a bundle for karma tests my system is maxing out of RAM and I get the JavaScript heap out of memory error. This happens both on my local machine that has 8gb RAM, and also on a gitlab runner hosted on digital ocean which has 4gb RAM.
Locally, if I kill all other apps, and set the memory allocation options node --max-old-space-size=4096 testscript.js I can sometimes get past the bundling, so I think it currently requires around 4gb+ RAM just to bundle, and this worries me. On the gitlab runner, linux terminates the docker container and I get the "killed" error
Before updating to weback 5 and therefore also before the memory issue my webpack configuration looked a bit differently, because webpack 5 doesn't include node libs by default, I have had to add some polyfills.
These are new in the configuration
crypto: false,
fs: false,
http: false,
path: require.resolve('path-browserify'),
stream: require.resolve('stream-browserify')
and these:
new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }),
new webpack.ProvidePlugin({ process: 'process/browser' }),
This is what the final webpack configuration for the karma bundling looks like:
const path = require('path');
const webpack = require('webpack');
const { excludeNodeModulesExcept } = require('../src/webpack/config');
const moduleListToTranspileForIE11 = ['debug', 'loader-utils', 'query-string', 'split-on-first', 'strict-uri-encode'];
const devModuleListToTranspileForIE11 = ['fetch-mock', 'proxy-polyfill', 'sinon', 'tr46', 'webidl-conversions', 'whatwg-url'];
module.exports = {
context: path.resolve(__dirname, '..'),
devtool: 'source-map',
entry: [
'./test/karma-webpack.main.js'
],
externals: {
'react/addons': true,
'react/lib/ExecutionEnvironment': true,
'react/lib/ReactContext': true
},
module: {
rules: [
{
test: /\.css$/,
use: [ 'css-loader', 'postcss-loader']
},
{
test: /\.js$/,
exclude: excludeNodeModulesExcept([].concat(devModuleListToTranspileForIE11, moduleListToTranspileForIE11)),
use: {
loader: 'babel-loader',
options: {
plugins: [
['#babel/plugin-transform-for-of', { assumeArray: true }]
],
presets: [
['#babel/preset-env', {}]
],
cacheDirectory: true // Note: for faster rebuilds
}
}
},
{
test: /\.svg$/,
loader: 'svg-react-loader'
}
]
},
mode: process.env.NODE_ENV || 'development',
resolveLoader: {
modules: [
'node_modules',
path.resolve(__dirname, '../src/webpack/loader')
]
},
output: {
path: path.resolve(__dirname, '../output/test'),
publicPath: '/',
filename: 'karma-webpack.js'
},
resolve: {
fallback: {
crypto: false,
fs: false,
http: false,
path: require.resolve('path-browserify'),
stream: require.resolve('stream-browserify')
}
},
performance: {
hints: false
},
plugins: [
new webpack.ProvidePlugin({ Buffer: ['buffer', 'Buffer'] }),
new webpack.ProvidePlugin({ process: 'process/browser' }),
new webpack.IgnorePlugin(/style\/demoHack\/\w+\.css/),
new webpack.IgnorePlugin(/app\.css/),
new webpack.IgnorePlugin(/config\/output\/build\/clientConfig\.json/),
new webpack.IgnorePlugin(/output\/local\/\w+\.json/)
]
};
The entry point ./test/karma-webpack.main.js looks like this:
require('./mocha.main');
var appReq = require.context('../src', true, /\.js$/);
appReq.keys().filter(function (key) {
return ['./react.main.js', './src/helper/polyfill.js'].indexOf(key) === -1 && !key.startsWith('./tool') && !key.startsWith('./src/test');
}).map(appReq);
// Only start mocha in browser.
if (!window.__karma__) {
window.mocha.run();
}
and is based on: https://github.com/FormidableLabs/full-stack-testing/blob/master/test/client/main.js
This seems to be including all mocha (file.test.js) files in the bundling, which makes it very slow, as those files also includes a lot of devDependencies. However, this was not a problem prior to the update. I have tried filtering out all files that are .test.js - then the bundling is fast, and I don't see any memory issues, however, karma is not running any tests then, the test suite is simply empty.
I am looking for advice with anything that could look suspicious about this configuration, and why it cannot bundle with less than 4gb memory available.

how to use `dependOn` to bundle separate application files from the main entry point?

I have a backend project that I would like to bundle using Webpack v5.
I would like to split some of the files into their own bundles and have them imported into the main entry.
The main entry has a dependOn key that contains an array of filenames that will be used by the main entry.
This is the webpack.config.json:
module.exports = {
entry: {
app: {
import: './index.ts',
dependOn: 'routes'
},
routes: ['./routes.ts']
},
output: {
filename: '[name].js',
libraryTarget: 'commonjs2',
path: path.resolve(__dirname, 'build')
},
resolve: {
extensions: ['.ts', '.js']
},
target: 'node',
externals: [
nodeExternals()
],
mode: 'production',
optimization: {
minimize: false,
},
module: {
rules: [{ test: /\.tsx?$/, loader: 'ts-loader' }]
},
plugins: [
new ContextReplacementPlugin(/any-promise/)
]
};
After running the build two files are generated (app.js & routes.js) as expected. But when running the entry point with NodeJS I get the following error: webpack_require.C does not exist.
Going through the documentation I see that their example dependOn is based on packages and not indvidual application files.
Can you add applicaton files to dependOn? Does this have something to do with module resolution?
Let me assume you have imported the routes in your app, and you want to split routes into a separate bundle instead of being included in the bundled app.js.
Here's how you could make it with SplitChunksPlugin https://webpack.js.org/plugins/split-chunks-plugin.
module.exports = {
entry: {
app: "./index"
},
target: "node",
optimization: {
splitChunks: {
cacheGroups: {
routes: {
filename: "routes.js",
test: module => {
return module.resource && module.resource.includes("routes");
},
enforce: true,
chunks: "all"
}
}
}
}
};
Webpack will output two files, app.js and routes.js.

Webpack Babel build fails when importing files outside entry path

I have this project that i'm already using webpack + babel to build. I've hit a wall since what i want to do is share some constants between my node (server) and my react app (front-end).
My project structure is this
- app
- internals
- webpack
- different webpack configs (node, react-dev, react-production etc)
- server
- shared
- .babelrc
I've put some "constants" files into the shared folder that I use both from my app and from my server.
When I try to build my server I get this
ERROR in ./shared/reports.constants.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
TypeError: Cannot read property 'code' of null
at transpile (C:\Users\XXX\Desktop\XXX\XXX\node_modules\babel-loader\lib\index.js:70:21)
at Object.module.exports (C:\Users\XXX\Desktop\XXX\XXX\node_modules\babel-loader\lib\index.js
:173:20)
Below is my webpack config file. Any ideas what might be wrong ?
{
mode: 'production',
target: 'node',
externals: nodeExternals(),
entry: {
server: [path.join(process.cwd(), 'server/index.js')],
},
output: {
filename: '[name].js',
path: path.resolve(process.cwd(), 'build'),
// sourceMapFilename: '[name].js.map',
},
devtool: 'hidden-source-map',
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract(
{ fallback: 'style-loader', use: { loader: 'css-loader', options: { minimize: true } } }),
},
{ test: /\.jpg$/, use: [{ loader: 'file-loader', options: { name: '/images/[name].[ext]' } }] },
{ test: /\.md$/, use: [{ loader: 'markdown-with-front-matter-loader' }] },
{
test: /\.js$/,
exclude: [/node_modules/],
include: [/server/, /shared/],
use: [
'babel-loader',
{
loader: 'webpack-preprocessor-loader',
options: {
debug: process.env.NODE_ENV !== 'production',
directives: {
secret: false,
},
params: {
ENV: process.env.NODE_ENV,
DEBUG: process.env.NODE_ENV !== 'production',
PRODUCTION: process.env.NODE_ENV === 'production',
ENVIRONMENT: process.env.ENVIRONMENT,
},
verbose: false,
},
},
],
},
],
},
plugins
etc
}
.babelrc file
{
"presets": [
"#babel/preset-env"
],
"plugins": [
"react-hot-loader/babel",
"#babel/transform-runtime",
"transform-html-import-to-string"
]
}
I've added the /shared/ to the includes rules.
Thank you in advance
For some reason I already had a babel.config.js + the babelrc. All I had to do was go into the babel.config.js and add the shared folder to be included in the env => production.
Thank you for your time

Deploy in production Outlook web-addin?

I am totally new to NodeJS, Webpack and especially to Outlook Addin.
However, when it came to deployment on Production, I struggled a lot. I put all my code up on Production (Ubuntu instance). Then I tried to start my Outlook Addin, just like I was doing locally, it started on port 3000, but there was no response to any API call and it is not showing any images which are static resources.
I want to know what could be the reason behind this and how to solve this problem.
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
polyfill: 'babel-polyfill',
app: './src/index.js',
'function-file': './function-file/function-file.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.html$/,
exclude: /node_modules/,
use: 'html-loader'
},
{
test: /\.(png|jpg|jpeg|gif)$/,
use: 'file-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
chunks: ['polyfill', 'app']
}),
new HtmlWebpackPlugin({
template: './function-file/function-file.html',
filename: 'function-file/function-file.html',
chunks: ['function-file']
})
]
};

Webpack 2: can't resolve node.js native modules

After bundling I have following errors:
Module not found: Error: Can't resolve 'crypto' in //filePath
It can't resolve five modules: crypto, fs, path, vm and constants - from any file which requires them
I thought it could be because of nvm which I use, but I switched to system nodejs via nvm use system command and webpack still throws these errors.
I also thought it could be target property, so I changed it to node, but it didn't help too (anyway I need electron-renderer, not node).
Important note: I've just migrated from webpack 1. It all works well before I migrated. But these are the only errors I have. Moreover, webpack seems to work fine, it even watches files when I pass --watch option.
Here is my webpack.config.js:
const config = {
target: 'electron-renderer',
context: __dirname,
entry: { app: './app.js', vendor: [/*vendors*/]},
cache: true,
devtool: 'source-map',
watch: false
resolve: {
extensions: ['.js', '.json', '.jsx'],
modules: ["node_modules"]
},
module: {
rules: [
{test: /\.html/, loader: 'html-loader'},
{
test: /\.less$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: ["css-loader?sourceMap", "less-loader?sourceMap"]
})
},
{
test: /\.css/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader?sourceMap"
})
},
{test: /\.(jpg|png|gif|jpeg|svg|otf|ttf|eot|woff)$/, loader: 'url-loader?limit=10000'}
]
},
plugins: [
new ExtractTextPlugin('styles.[contenthash].css'),
new webpack.optimize.CommonsChunkPlugin({
names: ['commons', 'vendor', 'manifest'],
minChuncks: Infinity
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
hash: false,
inject: 'head',
cashe: true,
showErrors: true
})
],
output: {
publicPath: './',
path: path.join(__dirname, 'dist'),
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js'
}
};
module.exports = config;
The problem was in worker-loader, which is not in my webpack.config.js (I used it directly when importing file). See this issue for details (not fixed yet).

Resources