Webpack output chunk as commonjs2 library - reactjs

I'm trying to make some React Isomorphic/Universal magic and I needed to be able to require in Node an exported chunk.
I'd like to do something like this:
webpack.config.js
module.exports = {
entry: {
index: [
'./src/index',
],
},
output: {
path: path.join(__dirname, '/dist'),
filename: '[name].js',
chunkFilename: 'chunk-[name].js',
libraryTarget: 'commonjs2',
},
...
};
index.jsx
require.ensure(['./reducers', './routes'], (require) => {
const rootReducer = require('./reducers');
const routes = require('./routes');
/* Store/routes/configuration stuff */
ReactDOM.render(/* components */);
}, 'core');
So this would output two files:
index.js: Loaded by the browser
chunk-core.js: required by index AND Node server
If I set the output as a library with type commonjs2 it works on Node, but does not generate my browser bundle, so I'd have to run 2 webpack configs simultaneously: one for the browser bundle and another for the server library.
I'd like to know if any of these are possible:
output a chunk as commonjs2 library
output a chunk with a different target as the main output
import a standard webpack chunk in Node

Related

Invalid hook call. When using external folders with webpack

I have divided my app into folders to be able to reuse code. My project consists of two folder common and common-web that I need to use in my customer-web-app project.
This is the directory structure
The customer-web-app is using razzle and its webpack config is
module.exports = {
modifyWebpackConfig({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
webpackConfig, // the created webpack config
webpackObject, // the imported webpack node module
options: {
razzleOptions, // the modified options passed to Razzle in the `options` key in `razzle.config.js` (options: { key: 'value'})
webpackOptions, // the modified options that will be used to configure webpack/ webpack loaders and plugins
},
paths, // the modified paths that will be used by Razzle.
}) {
console.log("TT:", webpackConfig, paths);
const copy = Object.assign({}, webpackConfig);
copy.resolve.modules = (copy.resolve.modules || []).concat([
path.resolve(__dirname, "../common-web/src"),
path.resolve(__dirname, "../common/src"),
path.resolve(__dirname, "../admin-common/src"),
]);
copy.resolve.alias = {
...(copy.resolve.alias || {}),
"#material-ui/core": path.resolve(
__dirname,
"./node_modules/#material-ui/core"
),
react: path.resolve("./node_modules/react"),
"react-dom": path.resolve("./node_modules/react-dom"),
"react-router-dom": path.resolve(
__dirname,
"./node_modules/react-router-dom"
),
"#common": path.resolve(__dirname, "../common/src"),
"#customer": path.resolve(__dirname, "../customer-common/src"),
"#web": path.resolve(__dirname, "../common-web/src"),
};
// Do some stuff...
return copy;
},
modifyWebpackOptions({
env: {
target, // the target 'node' or 'web'
dev, // is this a development build? true or false
},
options: {
webpackOptions, // the default options that will be used to configure webpack/ webpack loaders and plugins
},
}) {
webpackOptions.notNodeExternalResMatch = (request, context) => {
return /\#web|\#common|\#customer/.test(request);
};
webpackOptions.babelRule.include = webpackOptions.babelRule.include.concat([
path.resolve("../common-web/src"),
path.resolve("../common/src"),
path.resolve("../customer-common/src"),
]);
return webpackOptions;
},
};
But when I run the app its giving me
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

monaco-editor-webpack-plugin Create React App Build with react-router causing incorrect location for chunks

Getting the below error, it should be: http://localhost:4000/webapp/static/js/328.f5f431ed.chunk.js
This only happens for production builds and not development running.
It is appending to the end of the react router route. Not sure how to configure this properly?
Uncaught (in promise) ChunkLoadError: Loading chunk 328 failed.
(missing: http://localhost:4000/webapp/editor/ae2c222b-fc4b-40b7-bfae-7a0750c011fc/static/js/328.f5f431ed.chunk.js)
at Object.__webpack_require__.f.j (jsonp chunk loading:27:18)
Tried to change the config - tried different combinations of this and can't get it to work.
craco.config.js
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
webpack: {
output: {
publicPath: '/webapp/',
},
plugins: [new MonacoWebpackPlugin({ publicPath: '/webapp/', languages: ['json', 'python', 'shell', 'python']})],
},
};
Managed to figure this out
In package.json instead of
"homepage": ".",
use:
"homepage": "/webapp/",

Importing cdn of a local react webpack library giving a number in window object

I have two react projects where these two projects share some common components. I want to bundle those components as a library from project 1 with webpack and I don't want to publish them in any third party library tools, I want to use the project 1 cdn to get those components in project 2.
I followed this stackoverflow answer library of react components in webpack bundle export to use in on runtime rendering
but I'm getting Extract.entity value in window object as 1 (a number) instead of function or a class. This is my webpack config.
entry: {
app: paths.appIndexJs
},
output: {
path: paths.appBuild,
filename: "static/js/[name].js",
publicPath: publicPath,
library: ["Extract", "entity"],
libraryTarget: "umd",
umdNamedDefine: true,
globalObject: "this",
devtoolModuleFilenameTemplate: info =>
path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, "/")
}
The following is the output of window object in console
Extract:{
entity: 1
}

CRA webpack - output separate files

I've got a CRA app that I have built as a Chrome Extension, however I need to implement https://github.com/tshaddix/react-chrome-redux
To do so, I need to build my background.js as its own file, as well as the main.js
I've added my path to config/paths.js
backgroundJs: resolveApp('src/background.js'),
and my config contains:
entry: [require.resolve('./polyfills'), paths.appIndexJs],
output: {
path: paths.appBuild,
filename: 'static/js/[name].js',
publicPath: publicPath,
Does anyone know how I can keep my src file built into main.js, but have background.js build to its own file?
You can pass an object to entry:
module.exports = {
/* ... */
entry: {
main: [require.resolve('./polyfills'), paths.appIndexJs],
background: resolveApp('src/background.js'),
}
/* ... */
}
Check the document: https://webpack.js.org/concepts/entry-points/.

React multiple output files of bundle of single Input file

I am working in React and want to publish my code . I am creating bundle using webpack , since I want the bundle to be divided in three parts , that is , my code should have divided in to three different files so that not only one file get populated too much . I went through the official docs of webpack and other online sites but still not found the solution for this .
Here is a complete configuration webpack.config.js that you can base yours on.
const webpack = require('webpack');
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
const WebpackConfig = {
// multiple component entry points
entry: {
AppPart1: './src/AppPart1',
AppPart2: './src/AppPart2',
AppPart3: './src/AppPart3'
},
// generate files
output: {
path: './assets',
// creates JS files like "AppPart1.js"
filename: '[name].js'
},
module: {
preLoaders: [
// add any pre-loaders here, OPTIONAL
],
loaders: [
// add any loaders here, like for ES6+ transpiling, React JSX etc
]
},
resolve: {
extensions: ['.jsx', '.js']
},
plugins: [
// this will factor out some common code into `bundle.js`
new CommonsChunkPlugin('bundle.js'),
]
};
module.exports = WebpackConfig;
At the end of webpack build, here is what you will have in the assets folder
AppPart1.js
AppPart2.js
AppPart3.js
bundle.js
bundle.js will contain some shared code and must be included on all your pages along with the appropriate part file for the page.
If you have the three separate files, you can put multiple entry points on your webpack config:
entry: {
"bundle1":"./src/app/somefile1.jsx",
"bundle2":"./src/app/somefile2.jsx,
"bundle3":"./src/app/somefile2.jsx"
}

Resources