十九、1.noParse: 不解析不需要的依赖库,减少打包时间
$ mkdir webpack-optimize && cd webpack-optimize && yarn init -y
- 安装包:
$ cnpm i webpack webpack-cli html-webpack-plugin @babel/core @babel/preset-env babel-loader @babel/preset-react webpack-dev-server -D
- webpack.config.js
noParse: /jquery/, // 不去解析jquery中的依赖库
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
noParse: /jquery/, // 不去解析jquery中的依赖库
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets:[
'@babel/preset-env',
'@babel/preset-react'
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
二十、2.IgnorePlugin:打包时略过的插件
- 排除excloud和包含incloud
include: path.resolve('src'),exclude: /node_modules/,
- 安装包 moment ; 官网:momentjs.com;
- webpack.config.js
let webpack = require('webpack');
plugins: [
new webpack.IgnorePlugin(/\.\/locale/,/moment/), // 不去引用locale语言包
]
- src/index.js
let moment = require('moment');
import 'moment/locale/zh-cn'; // 单独引用zh-cn语言包,减少打包体积
moment.locale('zh-cn');
let time = moment().endOf('day').fromNow();
console.log(time);
二十一、3.dllPlugin:动态链接库
- 安装包react react-dom
- 使用
<div id="root"></div>
import React from 'react';
import { render } from 'react-dom';
render(<h1>jsx</h1>, window.root);
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let webpack = require('webpack');
module.exports = {
mode: 'development',
entry: './src/index.js',
devServer: {
port: 3000,
open: true,
contentBase: './dist'
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
include: path.resolve('src'),
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react' // 主要靠@babel-react插件实现 独立打包react文件
]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new webpack.IgnorePlugin(/\.\/locale/, /moment/),
]
}
- 独立文件的原理:通过引入js文件,把库通过变量导出到dist目录下
- 新建文件 webpack.config.test.js test.js
- webpack.config.test.js
let path = require('path');
module.exports = {
mode: 'development',
entry: {
test: './src/test.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
library: 'test', // 通过变量test拿到导出的值 var test = 'kft'
libraryTarget: 'var' // 默认var , umd、commonjs...
}
}
- test.js:
module.exports = 'kft'
- 执行npx webpack --config webpack.config.test.js 通过script导入test.js直接能拿到test = 'kft'
- 单独引入react和react-dom
- 新建 webpack.config.react.js
let path = require('path');
let webpack = require('webpack');
module.exports = {
mode: 'development',
entry: {
react: ['react', 'react-dom']
},
output: {
filename: '_dll_[name].js',
path: path.resolve(__dirname, 'dist'),
library: '_dll_[name]',
// libraryTarget: 'commonjs' // 默认var , umd
},
plugins: [
new webpack.DllPlugin({
name: '_dll_[name]',
path: path.resolve(__dirname, 'dist', 'manifest.json')
})
]
}
let webpack = require('webpack');
plugins: [
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist', 'manifest.json') // 查看manifest.json里是否有单独的库
}),
]
- 在src/index.html引入
<script src="_dll_react.js"></script>
*. React render render(jsx,window.root) devServer port open自动打开浏览器 contentBase './dist' 主要靠@babel-react插件实现 独立打包react文件 webpack.config.react.js test.js module.exports = 'kft' webpack.config.react.js path exports entry test.js output filename '[name].js' path dist library ab libraryTarget var react react-dom _dll_[name].js _dll_[name] plugins>.DLLPlugin() name path __dirname 'dist' 'manifest.json' webpack.config.js plugins> .DLLReferencePlugin manifest path.
二十二、4.happypack:多线程打包
- 安装包happypack
- 在使用loader时分配线程
let Happypack = require('happypack');
module: {
rules: [
{
test: /\.js$/,
include: path.resolve('src'),
exclude: /node_modules/,
use: 'Happypack/loader?id=js'
},
{
test: /\.css$/,
include: path.resolve('src'),
exclude: /node_modules/,
use: 'Happypack/loader?id=css'
}
]
},
plugins: [
new Happypack({
id: 'js',
use: [{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
]
}
}]
}),
new Happypack({
id: 'css',
use: ['style-loader','css-loader']
})
]
二十三、5.webpack自带优化:tree-shaking和scope hosting
- test.js
let sum = (a, b) => {
return a + b + 'sum';
}
let minus = (a, b) => {
return a - b + 'minus';
}
export default {
sum, minus
}
- index.js
// 使用import,在生产环境下打包会自动去除掉没有的代码,tree-shaking es6把没用的代码自动删除
// import calc from './test';
// console.log(calc.sum(1,2)); // 在生产环境下打包,只会打包sum函数,不会的打包minus函数
// let calc = require('./test'); // es6模块会把结果放到default上
// console.log(calc.default.sum(1,2)); // 在生产环境下,两个方法都会被打包
// 作用域提升 scope hosting
let a = 1;
let b = 2;
let c = 3;
let d = a + b + c;
console.log(d, '---------------------') // 在webpack中自动省略,可以简化代码,打包后 console.log(6,"---------------------")
二十四、6.抽离公共代码:多页面打包抽离公共代码和第三方插件
- +文件
- a.js
console.log('a~~~~~~~');
- b.js
console.log('b~~~~~~~');
- index.js/other.js
import './a'; import './b'; import $ from 'jquery'; console.log($);
- webpack.config.js +
entry: {
index: './src/index.js',
other: './src/other.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
optimization: { // commonChunkPlugins
splitChunks: { // 分割代码块
cacheGroups: { // 缓存组
common: { // 公共的模块
chunks: 'initial',
minSize: 0,
minChunks: 2
},
verdor: {
priority: 1, // 权重高,优先抽离出来
test: /node_modules/, // 把第三方插件抽离出来
chunks: 'initial',
minSize: 0,
minChunks: 2
}
}
}
},
二十五、7.懒加载
- 安装包:
@babel/plugin-syntax-dynamic-import
- webpack.config.js +
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-syntax-dynamic-import'
]
}
}
},
- src/index.js
let button = document.createElement('button');
button.innerHTML = '点击';
button.addEventListener('click',function(){
// es6草案中的语法,jsonp实现动态加载文件
import('./source.js').then((data)=>{
console.log(data.default);
})
})
document.body.appendChild(button);
- src/source.js
export default 'kft';
二十六、8.热更新:增量更新,不刷新页面
- webpack.config.js +
devServer: {
hot: true,
},
plugins: [
new webpack.NamedModulesPlugin(), // 打印更新的模块
new webpack.HotModuleReplacementPlugin() // 热更新插件
]
- src/index.js 使用热更新
// import str from './source';
if (module.hot) {
module.hot.accept('./source', () => {
let str = require('./source');
console.log(str)
})
}
webpack.config.js
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let webpack = require('webpack');
// let Happypack = require('happypack'); // 多线程打包配置
module.exports = {
optimization: { // commonChunkPlugins
splitChunks: { // 分割代码块
cacheGroups: { // 缓存组
common: { // 公共的模块
chunks: 'initial',
minSize: 0,
minChunks: 2
},
verdor: {
priority: 1,
test: /node_modules/, // 把第三方插件抽离出来
chunks: 'initial',
minSize: 0,
minChunks: 2
}
}
}
},
mode: 'production',
entry: {
index: './src/index.js',
},
devServer: {
// hot: true, // 热更新
port: 3000,
open: true,
contentBase: './dist'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
module: {
// noParse: /jquery/, // 不去解析jquery中的依赖库
rules: [
{
test: /\.js$/,
include: path.resolve('src'),
exclude: /node_modules/,
// use: 'Happypack/loader?id=js' // 多线程打包配置
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
],
plugins: [
'@babel/plugin-syntax-dynamic-import'
]
}
}
},
{
test: /\.css$/,
include: path.resolve('src'),
exclude: /node_modules/,
// use: 'Happypack/loader?id=css'
use: ['style-loader', 'css-loader']
}
]
},
plugins: [
// 动态链接库
// new webpack.DllReferencePlugin({
// manifest: path.resolve(__dirname, 'dist', 'manifest.json')
// }),
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// new webpack.NamedModulesPlugin(), // 打印更新的模块
// new webpack.HotModuleReplacementPlugin() // 热更新插件
// new webpack.IgnorePlugin(/\.\/locale/, /moment/), // 打包时略过moment包里的locale
// 多线程打包
// new Happypack({
// id: 'js',
// use: [{
// loader: 'babel-loader',
// options: {
// presets: [
// '@babel/preset-env',
// '@babel/preset-react'
// ]
// }
// }]
// }),
// new Happypack({
// id: 'css',
// use: ['style-loader','css-loader']
// })
]
}
package.json
{
"name": "webpack-optimize",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"build": "webpack --config webpack.config.js",
"dev": "webpack-dev-server"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.4.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel-loader": "^8.0.6",
"css-loader": "^3.0.0",
"happypack": "^5.0.1",
"html-webpack-plugin": "^3.2.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"style-loader": "^0.23.1",
"webpack": "^4.35.2",
"webpack-cli": "^3.3.5",
"webpack-dev-server": "^3.7.2"
},
"dependencies": {
"jquery": "^3.4.1",
"moment": "^2.24.0"
}
}