一.Treeshaking
幫助我們消除引用但未被使用的模塊
首先創建一個math.js文件
function square(x) {
return x * x;
}
function cube(x) {
return x * x * x;
}
export {square,cube};
index.js文件導入math.js中的cube方法,並且調用
import {cube} from './math.js';
console.log(cube(5));
打包後瀏覽器效果如下
現在打開我們打包後的main.js文件
我們沒有用到square方法,卻引入了所有function
爲精簡代碼,可以使用tree shaking
1.package.json 添加"sideEffects"
屬性
詳細用法如下:
2.webpack.config.js mode
設置爲production
3.打包
再次點開main.js文件
那麼我們假如不調用cube函數,會發生什麼
我們引入了math.js,但是沒有調用其中的任何方法,treeshaking連cube方法也沒打包進index.js。
這時用上我們的sideEffects屬性,看看效果如何
在main.js中還是找不到cube方法,沒有卵用啊
只好把index.js中的console.log(cube(5))加回來,再進行打包
能找到,但是我發現一個問題,我之前找不到是不是因爲我格式化了代碼。
再試一遍後發現,還真不是這個問題,只要index文件中沒有調用math裏的任何方法,就算加入
"sideEffects": ["./src/index.js"],
main函數也不會打包math.js的任何內容
那會不會是我的sideEffects用錯了?
同時index.js中仍舊註釋掉console.log(cube(5))
再次執行npx webpack打包,我們來看看main.js文件中的內容
仍舊未找到cube方法。
二.用webpack-merge合併config
1.安裝
npm install webpack-merge -D
2.創建config文件
將ebpack.config.js中的共同部分提取到commonConfig.js,其它的代碼分別提取到pro和dev兩個文件中,然後再引入common部分。同時package.json中的啓動代碼也需要修改
代碼提取到了三個文件中:
然後dev和pro合併common內容
同時修改 package.json中的啓動代碼
最後進行打包測試
npm run dev ||npm run pro
三.代碼分割
1.同步代碼需要配置webpack.config.js
optimization: {
splitChunks: {chunks: "all"}
}
2.異步代碼不需要配置
文檔:https://www.webpackjs.com/plugins/split-chunks-plugin/
四.代碼分析
配置package.json
"scripts": {
"dev_analyse" : "webpack --profile --json > stats.json --config webpack.dev.js"
},
運行npm run dev_analyse,會生成一個stats.json文件,上傳到http://webpack.github.io/analyse/
五.webpackPrefetch
把之前打印的header2進行預加載
Page.js:
export default function Page(){
this.header=document.createElement('div');
this.dom=document.getElementById("root");
//this.dom=document.getElementsByTagName("body")[0];
}
Page.prototype.appendChild=function(value){
this.header.innerText=value+2 ;
this.dom.appendChild(this.header);
}
index.js文件:
document.addEventListener('click',()=>{
import(/* webpackPrefetch: true */"./Page.js").then(
(Page)=>{
console.log(Page)
let page = new Page.default();
page.appendChild('header2');
}
)
})
這裏我調用Page構造函數時,用了 new Page.default();
也可以利用對象解構,如下:
document.addEventListener('click',()=>{
import(/* webpackPrefetch: true */"./Page.js").then(
({default:Page})=>{
console.log(Page)
let page = new Page;
page.appendChild('header2');
}
)
})
對象解構的知識可以查看:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
不過我第一次遇到這個是在TypeScript裏面,雖然沒太明白
在寫React Native時遇到了:https://blog.csdn.net/qq_34153210/article/details/106580372
六.分割css文件
1.安裝和配置
npm install --save-dev mini-css-extract-plugin
修改webpack.pro.js
const commonConfig =require("./webpack.common.js");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const merge=require("webpack-merge");
const proConfig= {
mode:"production",//"development",
devtool:'cheap-source-map',//關閉source map 使用 'none' //cheap-module-source-map
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
}
module.exports=merge(commonConfig,proConfig);
發現了一個錯誤
E:\learn\webpack-demo>npx webpack --config webpack.pro.js
WARNING: We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.
You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:
npm install --save core-js@2 npm install --save core-js@3
yarn add core-js@2 yarn add core-js@3
Error: No module factory available for dependency type: CssDependency
at addDependency (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:800:12)
at iterationOfArrayCallback (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:208:3)
at addDependenciesBlock (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:816:5)
at Compilation.processModuleDependencies (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:827:4)
at afterBuild (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:954:15)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:998:11
at callback (E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:734:5)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:782:12
at handleParseResult (E:\learn\webpack-demo\node_modules\webpack\lib\NormalModule.js:478:12)
at E:\learn\webpack-demo\node_modules\webpack\lib\NormalModule.js:500:6
at E:\learn\webpack-demo\node_modules\webpack\lib\NormalModule.js:358:12
at E:\learn\webpack-demo\node_modules\loader-runner\lib\LoaderRunner.js:373:3
at iterateNormalLoaders (E:\learn\webpack-demo\node_modules\loader-runner\lib\LoaderRunner.js:214:10)
at E:\learn\webpack-demo\node_modules\loader-runner\lib\LoaderRunner.js:186:6
at context.callback (E:\learn\webpack-demo\node_modules\loader-runner\lib\LoaderRunner.js:111:13)
at E:\learn\webpack-demo\node_modules\mini-css-extract-plugin\dist\loader.js:199:12
at E:\learn\webpack-demo\node_modules\webpack\lib\Compiler.js:343:11
at E:\learn\webpack-demo\node_modules\webpack\lib\Compiler.js:681:15
at AsyncSeriesHook.eval [as callAsync] (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:13:1)
at AsyncSeriesHook.lazyCompileHook (E:\learn\webpack-demo\node_modules\tapable\lib\Hook.js:154:20)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compiler.js:678:31
at AsyncSeriesHook.eval [as callAsync] (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:4:1)
at AsyncSeriesHook.lazyCompileHook (E:\learn\webpack-demo\node_modules\tapable\lib\Hook.js:154:20)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:1423:35
at AsyncSeriesHook.eval [as callAsync] (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:4:1)
at AsyncSeriesHook.lazyCompileHook (E:\learn\webpack-demo\node_modules\tapable\lib\Hook.js:154:20)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:1414:32
at eval (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:9:1)
at E:\learn\webpack-demo\node_modules\terser-webpack-plugin\dist\index.js:321:9
at TaskRunner.run (E:\learn\webpack-demo\node_modules\terser-webpack-plugin\dist\TaskRunner.js:48:7)
at TerserPlugin.optimizeFn (E:\learn\webpack-demo\node_modules\terser-webpack-plugin\dist\index.js:227:18)
at AsyncSeriesHook.eval [as callAsync] (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:5:1)
at AsyncSeriesHook.lazyCompileHook (E:\learn\webpack-demo\node_modules\tapable\lib\Hook.js:154:20)
at E:\learn\webpack-demo\node_modules\webpack\lib\Compilation.js:1409:36
at AsyncSeriesHook.eval [as callAsync] (eval at create (E:\learn\webpack-demo\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:4:1)
at AsyncSeriesHook.lazyCompileHook (E:\learn\webpack-demo\node_modules\tapable\lib\Hook.js:154:20)
E:\learn\webpack-demo\node_modules\neo-async\async.js:16
throw new Error('Callback was already called.');
^
Error: Callback was already called.
at throwError (E:\learn\webpack-demo\node_modules\neo-async\async.js:16:11)
at E:\learn\webpack-demo\node_modules\neo-async\async.js:2818:7
at processTicksAndRejections (internal/process/task_queues.js:79:11)
E:\learn\webpack-demo>
編輯我們的webpack.common.js
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
"presets": [["@babel/preset-env",
{
useBuiltIns: "usage",//表示只用babel轉化業務代碼ES6語法
"corejs": "3.0.0",
"targets": {
"esmodules": true,
"ie": "11"
}
},
],
// "@babel/preset-react",
],
// "plugins": [
// [
// "@babel/plugin-transform-runtime",
// {
// "absoluteRuntime": false,
// "corejs": 2,//默認false
// "helpers": true,
// "regenerator": true,
// "useESModules": false,
// "version": "7.0.0-beta.0"
// }
// ]
// ]
}
},
這時不會出現下面這段內容
WARNING: We noticed you're using the `useBuiltIns` option without declaring a core-js version. Currently, we assume version 2.x when no version is passed. Since this default version will likely change in future versions of Babel, we recommend explicitly setting the core-js version you are using via the `corejs` option.
You should also be sure that the version you pass to the `corejs` option matches the version specified in your `package.json`'s `dependencies` section. If it doesn't, you need to run one of the following commands:
npm install --save core-js@2 npm install --save core-js@3
yarn add core-js@2 yarn add core-js@3
我們關注一下Error: No module factory available for dependency type: CssDependency,看了半天,發現plugins忘記配置
plugins: [new MiniCssExtractPlugin()],
然後註釋掉上面添加的代碼
// "corejs": "3.0.0",
// "targets": {
// "esmodules": true,
// "ie": "11"
// }
執行打包命令 npx webpack --config webpack.pro.js,正常
文檔:https://webpack.js.org/plugins/mini-css-extract-plugin/#root
CSS代碼壓縮
安裝:
npm install --save-dev optimize-css-assets-webpack-plugin
編輯webpack.pro.js:
const commonConfig = require("./webpack.common.js");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const merge = require("webpack-merge");
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const proConfig = {
mode: "production",//"development",
devtool: 'cheap-source-map',//關閉source map 使用 'none' //cheap-module-source-map
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader'],
// use: [{loader: MiniCssExtractPlugin.loader,},
// {
// loader: "css-loader",
// options: {
// importLoaders: 2,
// modules: false
// }
// },]
},
],
},
plugins: [new MiniCssExtractPlugin()],
optimization: {
minimizer: [new OptimizeCSSAssetsPlugin({})],
},
}
module.exports = merge(commonConfig, proConfig);