Progressive configuration of webpack4 single and multiple pages
preface
Use the version of the package
Webpack ->4.3.0 babel-loader -> 8.0.5nPM ->6.4.1 webpack-cli ->3.3.1Copy the code
Each section corresponds to a demo
Build a multi-page configuration
Refer to DEMO12 for the specific code
Create a new multi-page directory
Create a new module file, specifying that each file in the module directory must have an HTML file and a JS file with the same name as the entry file.
Creating variable functions
Create a new method in help.js in the build folder
@param {array} [path address] * @param {array} [path address] * @return: {file name: file address} */ exports. GetEntry =function getEntry(globPath) {
var entries = {};
if(typeof(globPath) ! ="object") {globPath = [globPath]} globpath. forEach((itemPath) => {// glob.sync(itemPath).foreach (function(entry) {
entries[entry.substring(13, entry.lastIndexOf('. '))] = entry; / / 13 representative'./src/module/'
});
});
return entries;
};
Copy the code
Introduce multi-page files
inwebpack.base.jsInside the introduction of multi-page entry files
var entries = help.getEntry(['./src/module/**/*.js']); // Get the js file console.log(entries); /** Print the result {'demo/demo': './src/module/demo/demo.js'.'test/test': './src/module/test/test.js'} * * /Copy the code
Add to entry file
entry:Object.assign({},{app:help.resolve('./app.js')},entries),
Copy the code
inwebpack.base.jsIt introduces multi-page HTML files
function concatHtmlWebpackPlugin() {
var entriesHtml = help.getEntry(['./src/module/**/*.html']); Console. log(entriesHtml) /** Prints the result {'demo/demo': './src/module/demo/demo.html'.'test/test': './src/module/test/test.html' }
**/
var res = [];
for (var i in entriesHtml) {
var html = entriesHtml[i];
var obj = new htmlWebpackPlugin({
filename: '. ' + html.substring(html.lastIndexOf('/'), template: HTML, // HTML template path inject:true, // What is allowed to be modified by the plugin, including head and body chunks: ['vendors'Minify: {// Compress HTML file removeComments: isPord, // Remove HTML annotations collapseWhitespace: MinifyCSS: isPord // compression inline CSS},}) res.push(obj)}return res
}
Copy the code
Injecting multiple pages
plugins:[
new htmlWebpackPlugin({
filename:'index.html',
template:'./index.html',
inject:true,
chunks: ['vendors'.'app'], // Specify to import some entry files minify: {// compress HTML file removeComments: isPord, // remove HTML annotations collapseWhitespace: MinifyCSS: isPord // compression inline CSS},})]. Concat (concatHtmlWebpackPlugin())Copy the code
SplitChunks are configured by default
optimization: {
splitChunks: {
chunks: 'async',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true}}}},Copy the code
Run the command
npm run dev
Copy the code
Multi-page unpacking configuration
Refer to DEMO12 for the specific code
The JS files on each page introduce various packages
src/module/demo/demo.js
import axios from 'axios';
import xlsx from 'xlsx';
import dropzone from 'dropzone';
import lodash from 'lodash';
console.log(lodash);
console.log(dropzone);
console.log(xlsx);
console.log(axios);
var s=document.createElement('div')
s.innerHTML='dome file'
document.getElementById('app').appendChild(s);
Copy the code
Lodash, Dropzone, XLSX, and Axios are introduced.
src/module/test/test.js
import echarts from 'echarts';
import xlsx from 'xlsx';
import dropzone from 'dropzone';
console.log(dropzone);
console.log(xlsx);
console.log(echarts)
var s=document.createElement('div')
s.innerHTML='the test file'
document.getElementById('app').appendChild(s);
Copy the code
Dropzone, XLSX and Echarts are introduced.
app.js
import "regenerator-runtime/runtime";
import React from 'react';
import ReactDOM from 'react-dom';
import About from './src/view/about';
import Inbox from './src/view/inbox';
// import asyncComponent from './src/assets/js/AsyncComponent'
// const Inbox = asyncComponent(() => import( './src/view/inbox'));
// const About = asyncComponent(() => import( './src/view/about'));
import { BrowserRouter as Router, Switch, Redirect, Route, Link, HashRouter ,RouteChildren} from 'react-router-dom'
class App extends React.Component {
render() {
return (
<div className="shopping-list">
{this.props.children}
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/inbox">Inbox</Link></li>
</ul>
</div>
);
}
}
class Home extends React.Component {
render() {
return (
<HashRouter>
<Switch>
<App>
<Route path="/about" component={About} />
<Route path="/inbox" component={Inbox} />
</App>
</Switch>
</HashRouter>
)
}
}
ReactDOM.render(
<Home />,
document.getElementById('app'));Copy the code
React and react-dom packages are introduced.
Unpacking analysis
Demo.js and test.js use the same packages dropzone and XLSX. App.js only uses react and react-dom.
SplitChunks are configured by default.
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
name:'vendors',
chunks: 'all'.test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true}}}},Copy the code
Direct packaging
npm run build
Copy the code
npm run server
Copy the code
The results of
conclusion
Note The imported packages are packaged into a JS file, and each multi-page is loaded with extra packages. So the default configuration does not work well for multi-page unpacking.
Unpack and optimize the configuration
Modify splitChunks code
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true, cacheGroups: {reactVendors: {//reactVendors to match react related packet chunks:'all'.test: /(react|react-dom|react-dom-router)/,
priority: 100,
name: 'react',}, commonVendors: {// commonVendors to match XLSX and Dropzone packet chunks:'all'.test: /(dropzone|xlsx)/,
priority: 90,
name: 'commonMode',
},
vendors: {
name:'vendors',
chunks: 'all'.test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true}}}},Copy the code
Two matching items, commonVendors and reactVendors, are configured. Let’s see if we can.
npm run build
Copy the code
So the chunks don’t have to import packets so you have to import them.
Different import files introduce different chunks
So the app.js entry file needs to introduce react chunks.
new htmlWebpackPlugin({
filename:'index.html',
template:'./index.html',
inject:true,
chunks: ['vendors'.'app'.'react'CollapseWhitespace: isPord, // Delete whitespace and newlines minifyCSS: IsPord // compression inline CSS},})].concat(concatHtmlWebpackPlugin())Copy the code
Multiple pages need to introduce commonMode chunks.
function concatHtmlWebpackPlugin() {
var entriesHtml = help.getEntry(['./src/module/**/*.html']);
console.log(entriesHtml)
var res = [];
for (var i in entriesHtml) {
var html = entriesHtml[i];
var obj = new htmlWebpackPlugin({
filename: '. ' + html.substring(html.lastIndexOf('/'), template: HTML, // HTML template path inject:true, // What is allowed to be modified by the plugin, including head and body chunks: ['vendors',i,'commonMode'],// I represents the import file key minify: {// compress HTML file removeComments: isPord, // Remove HTML annotations collapseWhitespace: MinifyCSS: isPord // compression inline CSS},}) res.push(obj)}return res
}
Copy the code
After the configuration is complete.