基础库分离
html-webpack-externals-plugin
- 思路:将react、react-dom 基础包通过cdn引入,不打入bundle中
- 方法:使用
html-webpack-externals-plugin
- 下载包:
npm i html-webpack-externals-plugin -D
- 下载包:
// webpack.prod.js
'use strict';
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
module.exports = {
plugins: [
new HtmlWebpackExternalsPlugin({
externals: [
{
module: 'react',
entry: 'https://unpkg.com/react@17/umd/react.production.min.js',
global: 'React'
},
{
module: 'react-dom',
entry: 'https://unpkg.com/react-dom@17/umd/react-dom.production.min.js',
global: 'ReactDOM'
}
]
})
],
mode: 'production',
}
SplitChunksPlugin
- webpack4内置的,代替
CommonsChunkPlugin
插件 chunks
参数说明async
:异步引入的库进行分离(默认)initial
:同步引入的库进行分离all
:所有引入的库进行分离 ```javascript // webpack.prod.js ‘use strict’; const path = require(‘path’); const glob = require(‘glob’); const HtmlWebpackPlugin = require(“html-webpack-plugin”);
const setMPA = () => { const entry = {}; const htmlWebpackPlugins = []; const entryFiles = glob.sync(path.join(__dirname, ‘./src//index.js’)); Object.keys(entryFiles).map(item => { const entryFile = entryFiles[item]; const match = entryFile.match(/.src\/(.)\/index.js/); const pageName = match && match[1]; entry[pageName] = entryFile;
htmlWebpackPlugins.push(
new HtmlWebpackPlugin({
template: path.join(__dirname, `src/${pageName}/index.html`),
filename: `${pageName}.html`,
// 抽离出react和react-dom后,需要给htmlWebpackPlugin的chunks添加对应文件名
chunks: ['vendors', pageName],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
)
}) return { entry, htmlWebpackPlugins, } }
const { entry, htmlWebpackPlugins } = setMPA();
module.exports = { plugins: [
].concat(htmlWebpackPlugins), optimization: { splitChunks: { cacheGroups: { common: { // 匹配import的时候的名称 test: /(react|react-dom)/, // 打包出的文件的命名 name: ‘vandors’, chunks: ‘all’ } } }, }, mode: ‘production’, }
<a name="rG336"></a>
# 代码分割
- 意义:对于大的Web应用,将所有的代码都放在一个文件中显然是不够有效的,特别是当某些代码块是在某些特殊时候才会用到的。
- webpack有个功能就是将代码库分割成 chunks (语块),当代码运行到需要他们的时候再进行加载
- 使用场景
- 抽离相同的代码到一个共享块
- 脚本懒加载,使得初始下载的代码更小
<a name="Kz1Ig"></a>
## 懒加载JS的方式
- CommonJS:`require.ensure`
- ES6:动态import (目前没有原生支持,需要babel转换)
- 下载包:`npm i @babel/plugin-syntax-dynamic-import -D`
> 目录结构
> |-app
> |-node_modules
> |-.babelrc
> |-package.json
> |-webpack.prod.js
> |-src
> |-page
> |-index
> |-index.html
> |-index.js
> |-index.css
> |-text.js
> |-search
> |-static
> |-index.html
> |-index.js
> |-search.css
```javascript
// src/page/index/index.js
import { hello } from "./hello";
document.write(hello());
document.getElementById('btn').onclick = () => {
import('./text.js').then((text) => {
document.getElementById('text').innerHTML = text.default();
})
}
// .babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
'use strict';
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
const setMPA = () => {
const entry = {};
const htmlWebpackPlugins = [];
const entryFiles = glob.sync(path.join(__dirname, './src/page/*/index.js'));
Object.keys(entryFiles).map(item => {
const entryFile = entryFiles[item];
const match = entryFile.match(/.src\/page\/(.*)\/index.js/);
const pageName = match && match[1];
entry[pageName] = entryFile;
htmlWebpackPlugins.push(
new HtmlWebpackPlugin({
template: path.join(__dirname, `src/page/${pageName}/index.html`),
filename: `${pageName}.html`,
// 抽离出react和react-dom后,需要给htmlWebpackPlugin的chunks添加对应文件名
chunks: ['vendors', pageName],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false
}
})
)
})
return {
entry,
htmlWebpackPlugins,
}
}
const { entry, htmlWebpackPlugins } = setMPA();
module.exports = {
entry: entry,
output: {
path: path.join(__dirname, 'dist'),
filename: '[name]_[chunkhash:8].js',
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'less-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: { plugins: [['postcss-preset-env']] },
}
},
{
loader: 'px2rem-loader',
options: {
remUnit: 75,
remPrecision: 8
}
}
],
},
{
test: /\.(scss|sass)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpg|gif|jpeg|svg)$/,
use: [{
loader: 'file-loader',
options: {
name: 'img/[name]_[hash:8].[ext]'
}
}]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [{
loader: 'file-loader',
options: {
name: 'fonts/[name]_[hash:8].[ext]'
}
}]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name]_[contenthash:8].css'
}),
new CssMinimizerPlugin(),
new CleanWebpackPlugin(),
].concat(htmlWebpackPlugins),
optimization: {
splitChunks: {
cacheGroups: {
common: {
test: /(react|react-dom)/,
name: 'vandors',
chunks: 'all'
}
}
},
},
mode: 'production',
}
懒加载react
- 会有问题,不会解决