React multiple output files of bundle of single Input file - reactjs

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"
}

Related

How to move css-in-js (Styled Components) to an external css files during build using webpack - ReactJS

I am trying to figure out where the CSS files are residing when I build the react project. I am using webpack and I am able to make a single CSS file for all the styles used throughout the project if I use normal CSS. When I use CSS in js using styled component, I am not getting an external CSS file.
webpack.config.js
var path = require('path');
var hwp = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: path.join(__dirname, '/src/index.js'),
output: {
filename: 'index.js',
path: path.join(__dirname, './dist'),
publicPath : '/'
},
module:{
rules:[{
exclude: /node_modules/,
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.css$/i,
use: [
{
loader : MiniCssExtractPlugin.loader,
options : {
publicPath: '/public/path/to/',
},
},
'css-loader'
]
}
]
},
devServer: {
historyApiFallback: true,
},
plugins:[
new hwp({template:path.join(__dirname, '/src/index.html')}),
new MiniCssExtractPlugin({
filename : '[name].css',
chunkFilename : '[id].css',
})
]
}
Contact.js
import React from 'react'
import styled from "styled-components"
const Container = styled.div`
background-color : red;
`
function contact() {
return (
<Container>
<h1>
Welcome to Contacts page
</h1>
</Container>
)
}
export default contact
This isn't supported by styled-components at the moment. From a project member -
We don't support static CSS extraction. You can try out emotion which does.
You might not need static CSS extraction actually, because of several reasons:
There's SSR which sends only critical CSS, instead of all static CSS, for the entire page. You don't even need to do SSR, but can use snapshotting (react-snapshot) or generate a static page (gatsby, et al), which basically saves a SSR result to a html.
Static extraction doesn't generate dynamic CSS, which means your page will either appear broken until the JS executes, or you'll need to defer until the JS is loaded
Caching doesn't actually buy you an advantage, because the JS bundles will likely always change in tandem with the extracted CSS
In v3 we will add preprocessing, which will actually a bigger advantage. As part of that we might support an option for static extraction, since the core library that will bring preprocessing will probably also be integrated into emotion, which does support extraction. So it might become an option. Or not 😉
Source
Emotion has also removed static css extraction
Duplicate of How can I opt for React Styled-Components to generate a physical CSS file?

Webpack pdf file loader

This is the error:
"Build failed!
× ERROR ./media/fonts/handFont3.otf 1:4.
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./index.js 3:0-37
# ../node_modules/preact-cli/lib/lib/entry.js
# multi ../node_modules/preact-cli/lib/lib/entry webpack-dev-server/client webpack/hot/dev-server"
I'm trying to import pdf into preact component to make it build so I can get the link to the page with pdf file. Here is how:
import pdfFile from '../../media/images/pdfFile.pdf'
<a href={pdfFile} target="_blank"...
It didn't work, so I Googled this two solutions to add in wepback.config.js:
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif|pdf)$/,
use: ['file-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
},
]
},
};
and
{
test: /\.(pdf)$/,
use: ['url-loader']
},
I do manually make webpack.config work by this string:
--config webpack.config.js
And file is working, but result is the same. I'm still getting the error. And the same with otf fonts.
Thank you.
I figured out the solution. You can't use webpack config with preact config together.
So I removed webpack config and changed preact one to this:
export default (config, env, helpers, options) => {
const rule = {
test: /\.(otf|pdf)$/,
loader: 'file-loader'
}
config.module.rules.push(rule);
}

react lazy load external amd modules

My react app has external resources outside src/ so i have ejected react-scripts and disabled ModuleScopePlugin.
Referenced the external library in resolve.alias and used across the application.
resolve.alias: {
'genlib': path.resolve(fs.realpathSync(process.cwd()), 'lib/genlib/js/src'),
'config': path.resolve(fs.realpathSync(process.cwd()), 'config/dev'),
'messages': path.resolve(fs.realpathSync(process.cwd()), 'config/messages')
}
genlib is the external library im trying to reference.
The external library is AMD using requirejs.
One of the file in the library lazy loads a class using require.
define('class1', ['require', ...], function(require, ...) {
//
require([variable], function()...)
});
The above require is throwing Cannot find module 'xxx' at runtime from webpackEmptyContext.
When require from above code is consoled then below is logged instead of require function. Confused why webpackEmptyContext is consoled out instead of webpackContext function
Æ’ webpackEmptyContext(req) {
var e = new Error("Cannot find module '" + req + "'");
e.code = 'MODULE_NOT_FOUND';
throw e;
}
I have not changed any of the webpack.config.js except adding alias and disabling ModuleScopePlugin.
What else needs to be added or changed in config to lazy load amd modules.
webpack v4.19.1
react-dev-utils v7.0.1
I have solved by using ContextReplacementPlugin.
Added below code to webpack config plugins.
new webpack.ContextReplacementPlugin(/genlib[\\/]services/, /.*$/),
Now a map is created with all the files in the services directory and webpackContext loads the files when required.
You will see babel-loader in return object of webpack.config.js file. module -> rules array First code is to run the linter
{
test: /\.(js|mjs|jsx)$/,
enforce: 'pre',
use: [
{
options: {
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
],
include: [
paths.appSrc,
'paht/to/external-library/using/requirejs' <---- Add your external file path for loader to parse the AMD files
],
}
Similarly include file path to test entry of JS files
test: /\.(js|mjs|jsx|ts|tsx)$/,
Can you try this and check?

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/.

Webpack output chunk as commonjs2 library

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

Resources