webpack 2 multiple entries yet use react hot loader - javascript

I used this and it work in webpack 1
entry: {
vendor : ['react', 'react-dom', 'react-router', 'classnames', 'lodash', 'alt'],
app : ['webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
path.resolve(__dirname, PATHS.app, 'entries', 'app.js')],
otherFile : ['webpack-dev-server/client?http://localhost:8080',
'webpack/hot/only-dev-server',
path.resolve(__dirname, PATHS.app, 'entries', 'otherFile.js')]
}
But this won't work in webpack 2, it worked when I removed the landing property. How do I use HMR and multiple entires? in this guide https://webpack.js.org/guides/hmr-react/ it used array but in my case I'm also using multiple entries.

Could you add the complete config?
I was having an issue, but it turned out that the culprit was a misconfigured proxy.
I had it set to something like for webpack 1:
proxy: {
'/api*': {
target: 'http://0.0.0.0:3000',
secure: false
},
'/admin': {
bypass: () => 'admin.html'
}
},
But in webpack 2 I had to change it to:
proxy: {
'/api': {
target: 'http://0.0.0.0:3000',
secure: false,
bypass: (req, res, opts) => {
if (req.originalUrl === '/admin') {
return 'admin.html';
}
}
}
},
In your files, where are you trying to point path.resolve to? I have the webpack config on the root directory, and it lets me just do:
entry: {
main: [
'babel-polyfill',
'whatwg-fetch',
'react-hot-loader/patch',
'webpack-dev-server/client?http://0.0.0.0:8000',
'webpack/hot/only-dev-server',
'./app/components/main.jsx'
]
}

Related

digest-fetch and webpack - fetch is not a function

The Problem
TypeError: fetch is not a function
at DigestClient.fetch (webpack-internal:///./node_modules/digest-fetch/digest-fetch-src.js:48:24)
at User.create (webpack-internal:///./node_modules/mongodb-atlas-api-client/src/user.js:53:26)
at Function.createOrgDBUser (webpack-internal:///./src/OrgUtils.ts:87:51)
at Function.createOrg (webpack-internal:///./src/apis/OrgAPI.ts:373:39)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async APIResponse.processHandlerFunction (webpack-internal:///./node_modules/apilove/lib/APIResponse.ts:27:31)
That's the error I'm getting trying to use mongodb-atlas-api-client#2.3.1 to create indexes on a collection. I'm seeing this error locally and in aws-lambda.
atlasClient.user.create({...})
I use webpack to bundle my api so I think the issue is in how I'm bundling but in my research I haven't been able to come up with a solution.
digest-fetch, used by mongodb-atlas-api-client, uses node-fetch in absence of the native fetch function. However, I believe my webpack configuration coupled with the way digest-fetch imports the library is what's causing the issue.
The following line of code is from node-modules/digest-fetch/digest-fetch-src.js:8
if (typeof(fetch) !== 'function' && canRequire) var fetch = require('node-fetch')
If I change that to the below, everything works fine. In other words, it's importing the module not the main exported fetch function from node-fetch.
if (typeof(fetch) !== 'function' && canRequire) var fetch = require('node-fetch').default
The node-fetch/package.json describes three entry points.
"main": "lib/index.js",
"browser": "./browser.js",
"module": "lib/index.mjs",
I think what's happening is my webpack configuration is telling webpack to use the .mjs module entry point to build its output from node-fetch, which does export default fetch;.
My webpack.config.js
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const NodemonPlugin = require('nodemon-webpack-plugin')
const ZipPlugin = require('zip-webpack-plugin')
module.exports = (env, argv) => {
const config = {
target: 'node',
watchOptions: {
ignored: ['node_modules', '*.js', '*.js.map', '*.d.ts'],
},
entry: './src/APIHandler.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: `APIHandler.js`,
libraryTarget: 'commonjs',
},
optimization: {
minimize: false,
// minimizer: [new TerserPlugin({})],
},
resolve: {
extensions: ['.ts', '.json', '.mjs', '.js'],
},
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: 'ts-loader',
options: {
transpileOnly: true,
allowTsInNodeModules: true,
},
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new CopyPlugin([
{ from: path.join(__dirname, 'src/certs'), to: path.resolve(__dirname, 'dist', 'certs') },
]),
new NodemonPlugin(),
],
}
// eslint-disable-next-line no-console
console.log({ mode: argv.mode })
if (argv.mode === 'development') {
config.devtool = 'eval-cheap-module-source-map'
}
if (argv.mode === 'production') {
config.plugins.push(
new ZipPlugin({
filename: 'handler',
})
)
}
return config
}
FWIW, here's the version of each library currently installed in my node_modules. I'm using node v12.22.7 locally.
"digest-fetch": "1.2.1",
"mongodb-atlas-api-client": "2.31.0",
"node-fetch": "2.6.7",
"webpack": "4.46.0"
The Question
What am I missing? What change do I need to make to my webpack.config.js to have the require properly resolve to the main module export from node-fetch?
NOTE: In my research I've found other people having this problem but no resolutions that have helped me.
The solution was pretty simple. I added mainFields to the webpack config's resolve property.
resolve: {
extensions: ['.ts', '.json', '.mjs', '.js'],
mainFields: ['main', 'module'],
}
This tells webpack to first use the main property of a module's package.json, then fallback to the module property if it's not found.
For more information, see webpack's documentation.

Webpack, optimization chunking gives "Conflict: Multiple chunks emit assets to the same filename" error

Info
I am trying to generate my own webpack config and have some problems getting it working.
Problem
When trying to use optimization to split files into chunks I get the a error like underneath
Error: Conflict: Multiple chunks emit assets to the same filename static/js/bundle.js (chunks main and vendors-node_modules_react-hot-loader_patch_js-node_modules_react_jsx-dev-runtime_js-node_mod-4610d2)
If I remove the optimization section it works but without chunking. I have looked to the create react app webpack.config.js to get something to reference while generating this.
As you can see they have the optimization section working with chunking in both development and production. Why do I get the conflict error when using it?
Code
Minified/simplified version of my config (runtimeChunk disabled, as it also gives the same conflict error)
webpack.config.js
module.exports = () => {
process.env.NODE_ENV = "development";
process.env.BABEL_ENV = "development";
return {
mode: "development",
entry: ["react-hot-loader/patch", "./src"],
output: {
path: undefined,
publicPath: "/",
filename: "static/js/bundle.js",
chunkFilename: "static/js/[name].chunk.js",
},
optimization: {
minimize: false,
splitChunks: {
chunks: "all",
name: false
},
// runtimeChunk: {
// name: (entrypoint) => `runtime-${entrypoint.name}`,
// },
},
resolve: {
modules: [path.join(__dirname, "src"), "node_modules"],
alias: {
"react-dom": "#hot-loader/react-dom",
},
},
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: path.resolve(__dirname, "./src"),
exclude: /node_modules/,
use: ["babel-loader"],
},
],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
template: path.resolve(__dirname, "./public/index.html"),
}),
new webpack.HotModuleReplacementPlugin(),
],
devServer: {
compress: true,
hot: true,
contentBase: "./build",
historyApiFallback: true,
},
devtool: "inline-source-map",
};
};
.babelrc
{"presets": [["react-app", {"runtime": "automatic"}]]}
Got it to work had to change filename: "static/js/bundle.js" to filename: "static/js/[name].js"
output: {
path: undefined,
publicPath: "/",
filename: "static/js/[name].js",
chunkFilename: "static/js/[name].chunk.js",
}
If you are working on an ejected Create React App and you get a similar error
Multiple chunks emit assets to the same filename static/js/bundle.js
(chunks main and runtime-main)
you can just change the filename property in the output configuration from
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
to
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/[name].js',
Where the [name] placeholder is giving a different name to each output bundle instead of a fixed one.
In my case it was caused by the runtime-main.js file which I was generating with the runtimeChunk property inside optimization.
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`,
},

Webpack renames functions

Hello i have some problems with webpack. I have this config for webpack
module.exports = {
name: "front",
mode: "production",
context: path.resolve(__dirname, 'src'),
entry: [
'./jquery/photoswipe.addon_offer_and_order.min.js',
'./jquery/photoswipe.min.js',
'./jquery/photoswipe-ui-default.min.js',
'./deprecated.js',
'./index.js',
],
output: {
filename: "index.min.js",
path: path.resolve(__dirname, 'dist')
},
optimization: {
moduleIds: 'named'
}
}
All good but i have a deprecated.js and have all deprecated functions in it...
Example:
function updateSearchCharacteristic(url, category_id) {
console.warn("This method is deprecated please use shopSearch.updateCharacteristic()");
return shopSearch.updateCharacteristic(url, category_id);
}
function moveBlockAnfrageGuest() {
console.warn("This method is deprecated please use shopUser.moveOrderAndOfferLinkForGuest()");
return shopUser.moveOrderAndOfferLinkForGuest();
}
Webpack rename all these functions, if someone used the old functions, he does not see errors and the return does not work ..
How not to rename functions in this file, but compress
I resolved this problem :
npm install -D script-loader terser-webpack-plugin
Added a module into config and 'require' a plugin
const TerserPlugin = require('terser-webpack-plugin')
module: {
rules: [
{
test: /deprecated.js/,
use : [
{
loader: 'script-loader',
options:{
plugins: [
new TerserPlugin({
terserOptions: {
keep_fnames: true,
}
})
]
}
}
]
}
]
}

React : You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file(Local Node module)

I have babel loader in the library. Still after I add the library to the react application while yarn serve, I get the above error.
This is the webpack.dev.config.js (required in the webpack.config.js) in library-
//webpack.dev.config.js
const babelRCPath = require('#appfabric/infra-scripts').getConfigPath('babel', 'plugin');
const babelRCGenerator = require(babelRCPath);
const babelRC = babelRCGenerator([]);
module.exports = {
{
BaseModule: `${process.cwd()}/src/BaseModule`,
BaseObject: `${process.cwd()}/src/BaseObject`,
BaseWidget: `${process.cwd()}/src/widgets/BaseWidget`,
HOCWidget: `${process.cwd()}/src/widgets/HOCWidget`,
PortalWidget: `${process.cwd()}/src/widgets/PortalWidget`,
BaseActivator: `${process.cwd()}/src/application/BaseActivator`,
CorePlugin: `${process.cwd()}/src/application/CorePlugin`,
BaseAppDelegate: `${process.cwd()}/src/application/appdelegates/BaseAppDelegate`,
EmbeddedAppDelegate: `${process.cwd()}/src/default/appdelegates/embedded/EmbeddedAppDelegate`,
ActionType: `${process.cwd()}/src/application/appdelegates/actions/ActionType`,
types: `${process.cwd()}/src/application/appdelegates/actions/types`,
CommandActionType: `${process.cwd()}/src/application/appdelegates/actions/CommandActionType`,
CommandForResponseActionType: `${process.cwd()}/src/application/appdelegates/actions/CommandForResponseActionType`,
PluginRegistryService: `${process.cwd()}/src/default/PluginRegistryService`,
},
mode: 'development',
externals: [
'dcl',
'react',
'react-dom',
'prop-types',
'pubsub',
'semver',
'#appfabric/ui-profiler',
].map(
// Add this regex to each entry to ensure we don't miss any imports like 'web-shell-core/...`
(value) => new RegExp(`^(${value})((\\\\|/|!).+)?$`),
),
output: {
path: `${process.cwd()}/build/dist`,
filename: '[name].js',
library: 'web-shell-core',
libraryTarget: 'umd',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader: 'babel-loader',
options: babelRC,
},
},
],
},
};
This is the webpack.config.js
const developmentConfig = require('./webpack.dev.config.js');
module.exports = merge(developmentConfig, {
mode: 'production',
output: {
filename: '[name].min.js',
chunkFilename: '[name].min.js',
},
});
First I add a new file Secure.jsx(having the tags) in the library. I do npm install --save <path-to-library> on my application. After I do yarn install. Then I can see the new file Secure.jsx in the node modules in the application. When I try to run the application, I get the error.
Please let me know what am I missing and also which side(library / application) I have to add the code.
You can view my full config here
I think you also need to add this
resolve: {
modules: [
path.resolve('./node_modules')
]
},
Then import like this
import "jquery/dist/jquery.min.js";
import "bootstrap/dist/js/bootstrap.min.js";

how to create 2 different javascript files with different webpack configurations?

I need to create 2 different JavaScript and CSS files, one minimized and the other one not.
I want to render the not minimized files only in Chrome, for the other browsers I want the regular minimized and compresed code.
I've tried with preset-env, changing the .babelrc file, I even tried with browserlist.
webpack.dev.js
const merge = require('webpack-merge');
const loaders = require('./webpack.loaders');
const plugins = require('./webpack.plugins');
const common = merge([{
mode: 'development',
entry: {
main: [
'./src/main/resources/js/index.js'
],
sitemap: [
'./src/main/resources/js/indexSiteMap.js'
],
error: [
'./src/main/resources/js/error/error.js'
],
icons: [
'./src/main/resources/js/fonts/google.js',
'./src/main/resources/js/fonts/features.font.js',
'./src/main/resources/js/fonts/generals.font.js'
]
},
output: {
filename: '[name].js',
chunkFilename: '[name].js'
},
devtool: 'source-map',
optimization: {
splitChunks: {
cacheGroups: {
libs: {
test: /node_modules/,
name: "libs",
chunks: "initial",
enforce: true
}
}
}
}
},
loaders.loadSass(),
loaders.loadHandlebars(),
loaders.loadReact(),
loaders.loadFileLoader(false),
loaders.loadFonts(false),
loaders.loadExpose(),
loaders.loadEslint(),
]);
module.exports = () => {
return merge([
common,
plugins.clean(),
plugins.extractCSS(false),
plugins.copy()
]);
}
.babelrc
{
"presets": ["#babel/env", "#babel/react"]
}
I get two different JavaScript files, the common.js and the modern.js
I'll load the modern -not minimized- file in chrome, otherwise I'll use the common.js file
You will need 2 different webpack configs, pass command line arguments like the below:
webpack --env.browser=chrome --open 'Google Chrome'
webpack --env.browser=other --open safari
And maintain 2 different webpack configs in webpack.chrome.js and webpack.other.js
and put this in webpack.config.js
module.exports = env => require(`./webpack.${env}.js`);
You will also need 2 different local servers or webpack-dev-server configs running in different ports like the below:
webpack.chrome.js
mode: 'production',
devServer: {
compress: true,
contentBase: path.join(__dirname, './dist'),
port: 9000,
},
webpack.other.js
mode: 'development',
devServer: {
contentBase: path.join(__dirname, './dist'),
port: 9001,
},

Categories