webpack 进阶1014

webpack 进阶

1.JS-Tree-Shaking(过滤)

<body>
<!--
1.什么是Tree-Shaking?
过滤掉无用的JS代码和CSS代码, 我们称之为Tree-Shaking
例如: 在a.js中引入了b模块, b模块中有2个方法, 但是我只用到了1个方法
默认情况下会将b模块中所有代码都打包到a.js中,
为了提升网页性能降低打包体积, 我们可以只将用到的方法打包到a.js中

2.webpack中如何开启Tree-Shaking?
https://www.webpackjs.com/guides/tree-shaking/
2.1开发环境
webpack.config.js配置, 告诉webpack只打包导入模块中用到的内容
optimization: {
   usedExports: true
},
package.json配置, 告诉webpack哪些文件不做Tree-Shaking
"sideEffects": ["*.css", "*.less", "*.scss"],

2.2生产环境
无需进行任何配置, webpack默认已经实现了Tree-Shaking

注意点:
- 只有ES Modle导入才支持Tree-Shaking
- 任何导入的文件都会受到 tree shaking 的影响。
这意味着,如果在项目中使用类似 css-loader 并导入 CSS 文件,
则需要将其添加到 side effect 列表中,以免在生产模式中无意中将它删除:
-->
</body>

2.CSS-Tree-Shaking

<body>
<!--
1.CSS模块Tree-Shaking
不光JS模块可以进行Tree-Shaking, CSS模块也可以进行Tree-Shaking

2.如何开启CSS模块Tree-Shaking
https://github.com/webpack-contrib/purifycss-webpack
2.1安装相关插件
npm i -D purifycss-webpack purify-css glob-all
2.2配置插件
const PurifyCSS = require("purifycss-webpack");
const glob = require("glob-all");

new PurifyCSS({
    paths: glob.sync([
        // 要做CSS Tree Shaking的路径文件
        path.resolve(__dirname, "./*.html"),
        path.resolve(__dirname, "./src/js/*.js"),
    ])
}),
-->
</body>

3. 代码分割

<body>
<!--
1.什么是Code-Splitting(代码分割)?
默认情况下webpack会将所有引入的模块都打包到一个文件中,
这样就导致了打包后的文件比较大, 以及修改文件后用户需要重新下载所有打包内容问题
例如: 在a.js中引入了b.js, 那么a.js和b.js都会被打包到bundle.js中
      如果a.js有1MB, b.js也有1MB, 那么打包之后的文件就有2MB
      那么用户第一次打开网页的时候就需要下载2MB的文件
      问题的关键在于, 如果我们修改了a.js, 但没有修改b.js
      重新打包后用户需要重新下载新打包的文件(因为用户本地缓存的是a和b的合体)
      这样就导致了每次修改了其中一个文件用户都要重新下载所有内容
解决方案: 将不经常修改的内容打包到另一个文件中, 这样每次修改后用户就只用下载修改后的文件
          没有被修改的文件由于用户上一次打开已经缓存在了本地就不用下载了, 这样性能也提升了
Code-Splitting就是将不经常修改的模块打包到单独的文件中, 避免每次修改用户都需要重新下载所有内容

2.如何开启Code-Splitting
2.1手动分割(了解)
- 在单独文件中引入模块, 将模块中的内容添加到window上
- 修改配置文件同时打包多个文件
比如我们在一个文件中引入jquery
import $ from 'jquery';
window.$ = $;
然后在index.js中使用
window.$('html').css({ width: '100%', height: '100%' });
这样当我们修改index.js的时候用户只需要下载这一个文件就行了
entry: {
    calculate: "./src/js/calculate.js", // 先打包会被先引入
    main: "./src/js/index.js",
},
output: {
    filename: "js/[name].js",//这个name就是入口函数的key
    path: path.resolve(__dirname, "bundle")
},

2.2自动分割(用这个)
webpack会自动判断是否需要分割, 如果需要会自动帮助我们分割,不需要我们手动来设置文件名字等
optimization: {
    splitChunks: {
        chunks: "all"
    }
},
-->
</body>

4.异步加载

<body>
<!--
1.什么是异步加载模块?
同步加载: import $ from 'jquery';
例如: 在index.js中导入了10个模块, 那么只要index.js被执行, 就会一次性将10个模块加载进来
异步加载: import('jquery').then(({default: $ }) => {使用模块代码});
例如: 在index.js中导入了10个模块, 那么哪怕index.js被执行, 也要看是否满足加载条件才去加载
const oBtn = document.querySelector('button');
oBtn.onclick = function() {
    getComponment().then(($div) => {
        document.body.appendChild($div[0]);
    });
};
function getComponment() {
    return import('jquery').then(({ default: $ }) => {
        const $div = $('<div>我是div</div>');
        return $div;
    });
}

特点:
对于异步加载的模块无需配置, webpack会自动分割,所以就不用进行我们上面所说的代码分割
https://webpack.js.org/guides/lazy-loading/
-->
</body>

5.魔法注释

<body>
<!--
1.什么是Prefetching and Preloading
通过异步加载(懒加载)的方式确实可以优化我们的代码
但是也存在一定的弊端, 弊端就是用到的时候再加载, 那么用户需要等待加载完成后才能使用
例如: 弹出登录框的时候有一些业务逻辑, 如果这些业务逻辑使用懒加载的话, 那么只有加载完用户才能操作登录框

解决方案:
加载完当前需要使用的所有模块之后, 在空闲的时间提前把异步加载的模块也加载进来
这样既不会影响到第一次的访问速度, 还可以提升异步加载的速度较少用户等待的时间

所以就有了Prefetching和Preloading
Prefetching: 空闲的时候加载
也就是等当前被使用的模块都加载完空闲下来的时候就去加载, 不用等到用户用到时再加载
Preloading: 和其它模块一起加载(不推荐, 了解即可)
也就是和当前被使用的模块一起加载

3.使用方式
https://webpack.js.org/guides/code-splitting/#prefetchingpreloading-modules
异步加载时写上魔法注释即可
/* webpackPrefetch: true */
/* webpackPreload: true */
比如在上面加载jquery的时候这样写
import(* webpackPrefetch: true */'jquery').then(({ default: $ })
4.利用魔法注释修改分割代码的名称
- 异步加载时在加载模块前面写上魔法注释
import(/* webpackChunkName: "jquery" */"jquery").then();
-->
</body> 

6. 长缓存优化

<body>
<!--
1.浏览器缓存问题
浏览器会自动缓存网页上的资源, 以便于提升下次访问的速度
但正式因为浏览器的缓存机制,  导致文件内容被修改之后只要文件名称没有发生变化
就不会重新去加载修改之后的资源, 所以刷新网页后显示的还是修改之前的内容
为了解决这个问题, 我们就需要在打包文件的时候给"文件名称加上内容的hash值"
一旦内容发生了变化, 内容的hash值就会发生变化, 文件的名称也会发生变化
一旦文件的名称发生了变化, 浏览器就会自动去加载新打包的文件

2.hash/chunkhash/contenthash
hash:
根据每次编译打包的内容生成的哈希值, 每次打包都不一样, 不能很好利用缓存, 不推荐
chunkhash:
根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。
在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,
接着我们采用chunkhash的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。
注意点: 只支持css和js, 不支持img等其它资源
contenthash(推荐):
根据某个文件内容生成的哈希值, 只要某个文件内容发生改变,该文件的contenthash就会发生变化

注意点: 在webpack4中contenthash和热更新有冲突, 所以在开发模式想使用contenthash需要关闭热更新
        但是一般情况下我们需要通过hash解决的是线上代码的内容更新问题, 所以开发模式无关紧要

3.manifest
webpack在打包时,会把库和业务代码之间的关系做manifest,
它既存在于业务代码(main.js),也存在于库中(vendor.js),
在旧版webpack中(webpack4之前),mainfest在每次打包的时候的时候可能会变化,
所以contenthash值也会跟着变化。配置runtimeChunk后,会把manifest提取到runtime中,
这样打包就不会影响到其他js了。
optimization: {
    runtimeChunk: "single",
    splitChunks: {
        chunks: "all",
    },
}
-->
</body>

7.SplitChunksPlugin(代码分割的原理)

<body>
<!--
1.什么是Split-Chunks-Plugin?
webpack在代码分割的时候底层使用的其实是Split-Chunks-Plugin来实现代码分割的
所以这个插件的作用就是进行代码分割,需要配置相关属性

2.Split-Chunks-Plugin相关配置
https://www.webpackjs.com/plugins/split-chunks-plugin/
/*告诉webpack需要对代码进行分割*/

optimization: {
    splitChunks: {
        chunks: 'all', // 对那些代码进行分割 async(只分割异步加载模块)、all(所有导入模块)
        minSize: 30, // 表示被分割的代码体积至少有多大才分割(单位是字节)
        minChunks: 1, // 表示至少被引用多少次数才分割,默认为1
        maxAsyncRequests: 5, // 异步加载并发最大请求数(保持默认即可)
        maxInitialRequests: 3, // 最大的初始请求数(保持默认即可)
        automaticNameDelimiter: '+', // 指定被分割出来的文件名称的连接符
        name: true, // 拆分出来块的名字使用0/1/2... 还是指定名称
        /*
        cacheGroups: 缓存组
        缓存组的作用: 将当前文件中导入的所有模块都缓存起来统一处理
        举个例子
        import $ from 'jquery'; // npm install jquery
        import _ from 'lodash'; // npm install lodash
        默认情况下如果所有的模块都是从node_modules中导入的,
        那么会将所有从node_modules中导入的模块打包到同一个文件中去(如上)

        import { add, minus } from './custom.js';
        import { hello, hi } from './custom2.js';
        如果当前文件中导入的模块有的是从node_modules中导入的, 有的不是从node_modules中导入的
        那么就会将所有从node_modules中导入的打包到一个文件中
        那么就会将所有不是从node_modules中导入的,中导入的打包到另一个文件中
     
        cacheGroups: {
            /*
            vendors: 专门用于处理从node_modules中导入的模块
                     会将所有从node_modules中导入的模块写入到一个文件中去
            */
            vendors: {
                test: /[\\/]node_modules[\\/]/,
                priority: -10 // 抽取公共代码的优先级,数字越大,优先级越高
            },
            
            /*default: 专门用于处理从任意位置导入的模块
                     会将所有从任意位置导入的模块写入到一个文件中去*/          
            
            /* 注意点: 如果我们导入的模块同时满足了两个条件, 那么就会按照优先级来写入
            例如: 我们导入了jQuery, jQuery存放在了node_modules目录中
            所以满足vendors的条件, 也满足default条件, 但是vendors的条件的优先级高于default的优               先级
            所以就只会执行vendors规则, 只会写入到vendors对应的文件中去
            */
            default: {
                minChunks: 1, // 表示至少被引用多少次数才分割,默认为1
                priority: -20,
                /*比如有个c.js文件,然后我有index1.js,index2.js都引用了c这个文件,打包后就会产生两个                 分割的c.js文件,为了不产生两个,就设为true*/
                reuseExistingChunk: true // 是否复用分割的代码(设为true就行)
            }
        }
    }
},
-->
</body>

8. Provide-Plugin(不用到处引入)

<body>
<!--
1.模块各种引入方式
1.1在HTML中全局引入
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
特点: 什么地方都可以使用
1.2通过npm安装通过import局部引入
特点: 只能在import导入的模块中使用
默认情况下模块中的数据都是私有的, 所以想要使用模块必须先导入模块
如果说在a.js中想要使用jQuery, 那么就必须在a.js中导入jQuery模块
如果说在b.js中想要使用jQuery, 那么就必须在b.js中导入jQuery模块

2.什么是Provide-Plugin?
https://www.webpackjs.com/plugins/provide-plugin/
自动加载模块,而不必到处 import 或 require,是一个私有的属性,只需要在webpack文件中引入webpack模块
然后进行以下配置,以后就能使用了 
const Webpack = require('webpack');
new Webpack.ProvidePlugin({
    $: "jquery"
})
-->
</body>

9.imports-loader(也是实现全局导入,修改全局this)

<body>
<!--
1.什么是imports-loader?
https://www.webpackjs.com/loaders/imports-loader/
https://www.npmjs.com/package/imports-loader
imports-loader和Provide-Plugin功能一样可以实现全局导入,
但是imports-loader的功能比Provide-Plugin更强大,
imports-loader除了可以实现全局导入以外, 还可以修改全局this指向
默认情况下模块中的this指向一个空对象, 我们可以通过imports-loader实现让this指向window
使用
1.1安装import-loader
npm install imports-loader
1.2配置
在打包js规则时增加以下
{
     test: /\.js$/,
     exclude: /node_modules/, // 告诉webpack不处理哪一个文件夹
     // 以下代码的含义: 但凡在JS中用到了$就去自动加载jQuery
     // loader: 'imports-loader?$=jquery'
     // 以下代码的含义: 修改模块中this的指向
     loader: 'imports-loader?this=>window'
 },

2.imports-loader注意点:
2.1在企业开发中如何需要实现全局导入, 更推荐使用ProvidePlugin来实现
   因为ProvidePlugin是webpack内置的官方插件更靠谱
2.2.1使用imports-loader修改this指向, 系统会自动将我们的代码放到一个立即执行函数中
(function () {
    // my module
}.call(window));
*/
/*
2.2.2如果在模块中用到了import, 那么在ES Module的规范中
import语句必须写在最前面, 否则就会报错
*/
/*
3.所以如果通过imports-loader修改了模块中this的指向,
而在模块中又用到了import, 这就导致了在打包时候import不在第一行, 会报错
比如我们引用在index.js中引入jquery
import $ from 'jquery';
但是在修改this打包后就成了
(function () {
    import $ from 'jquery';//此时最前面不是import了
}.call(window));

2.3如何解决?
无需修改this指向, 直接在模块中使用window
或者导入模块的时候不要用import导入而是用node.js的require导入(但是不推荐)
-->
</body>

10. resolve(简化引入包的写法)

<body>
<!--
3.什么是resolve?
https://www.webpackjs.com/configuration/resolve/
resolve用于配置导入模块的解析规则

4.resolve常用配置
4.1映射导入路径, 简化导入代码
比如我们想使用bootstrap,但是直接这样写// import 'bootstrap';
他会去找bootstrap的package.json里面的main,这个main对应的不是bootstrap.css的路劲
那么在下面的代码就不能使用bootstrap定义的类,那该怎么解决呢

import 'bootstrap/dist/css/bootstrap.css';
   但是这种写法每次都要写很长的一串路径, 有没有办法可以简化呢?
   那就是通过resolve
resolve: {
    // 创建 import 或 require 的别名,来确保模块引入变得更简单
    alias: {
        bootstrap: path.resolve(__dirname, "bootstrap/dist/css/bootstrap.css")
        bootstrap: 'bootstrap/dist/css/bootstrap.css'
    },
}

4.2修改入口查找顺序, 简化导入代码(第二种)
resolve: {
    // 指定模块入口的查找顺序
    mainFields: ["style", "main"],
}

4.3修改查找顺序, 简化导入代码
resolve: {
    // 指定导入模块查找顺序
    extensions: [".css", ".js"]
}

4.4通过import导入模块的时候会先在node_modules中查找, 找不到再逐级向上查找
   这样在打包的时候非常消耗性能, 能不能在打包的时候让webpack只去指定的目录查找
   那就是通过resolve的modules
resolve: {
    // 指定查找范围, 告诉webpack只在node_modules中查找
    modules: ["node_modules"],
}
-->
</body>

11.noparse(依赖关系)

<body>
<!--
1.什么是noParse属性?
默认情况下无论我们导入的模块(库)是否依赖于其它模块(库), 都会去分析它的依赖关系
但是对于一些独立的模块(库)而言, 其根本不存在依赖关系, 但是webpack还是会去分析它的依赖关系
这样就大大降低了我们打包的速度.
所以对于一些独立的模块(库), 我们可以提前告诉webpack不要去分析它的依赖关系
这样就可以提升我们的打包速度.

那么如何告诉webpack这是一个独立的模块(库)呢?
我们可以通过noParse属性来告诉webpack
在webpack配置文件中添加
noParse: /jquery/  就表示不需要分析jquery的依赖关系
-->
</body>

12.IgnorePlugin(忽视某个目录)

<body>
<!--
1.什么是IgnorePlugin?
IgnorePlugin是webpack的一个内置插件
IgnorePlugin用于忽略第三方包指定目录,让指定目录不被打包进去

比如现在我们有一个库叫momunt,是一个和时间日期有关的库
但是这个库里面要包含各种语言,对应的各种语言的文件放在一个locale目录下
但我们只要使用中文,那么这个目录下的其他国家的语言就没用,所以为了快点打包,就可以忽略其他国家的语言

2.使用
2.1首先如下配置
/*
以下代码的含义:
在打包moment这个库的时候, 将整个locale目录都忽略掉
*/
new Webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)

2.2然后在index.js打包的时候就如下引用
import moment from 'moment';
import 'moment/locale/zh-cn.js'; //特地引入中文
2.3 正常使用
-->
</body>

13.externals(不打包第三方库)

<body>
<!--
1.什么是externals?
externals的作用就是将不会发生变化的第三方模块(库)设置为外部扩展,
避免将这些内容打包到我们的项目中, 从而提升打包速度

2.externals使用
https://www.webpackjs.com/configuration/externals/
2.1手动全局引入第三方模块
在html中全局引入
<script src="https://code.jquery.com/jquery-3.4.1.js"></script>
2.2在配置文件中告诉webpack这是一个外部扩展库, 不需要打包
externals: {
    /*
    以下配置的含义:
    告诉webpack我们在通过import导入jquery的时候, 不是导入node_modules中的jquery
    而是导入我们全局引入的jquery
    * */
    jquery: 'jQuery',
    lodash: '_'
}
-->
</body>

14. dll动态链接库

<body>
<!--
1.什么是dll动态链接库?
dll动态链接库和externals功能其实是一样的,
都是用于防止重复打包不会发生变化的第三方模块,
都是用于提升webpack打包效率的
只不过externals不太符合前端的模块化思想, 所以就有了dll动态链接库


2.如何实现让第三方模块只打包一次
2.1单独配置一个config.js文件打包不会发生变化的第三方库
module.exports = {
    mode: 'production',
    entry: {
        vendors: 'jquery'
    },
    output: {
        filename: '[name].[contenthash:8].js',
        path: path.resolve(__dirname, 'dll'),
        library: '[name]' // 表示打包的是一个库, 表示将打包的内容通过全局变量暴露出去
    }
};
2.2通过插件将打包好的库引入到html文件上
npm install --save-d add-asset-html-webpack-plugin
new AddAssetHtmlWebpackPlugin({
    filepath: path.resolve(__dirname, 'dll/vendors.js')
})
注意点: 该插件需要配合HtmlWebpackPlugin使用, 并且需要在HtmlWebpackPlugin后创建

2.3生成动态库的映射关系(库的清单)
因为我们有可能将几个库打包到一个文件中, 所以需要生成一个映射文件方便webpack能够从中找到对应的库
以下配置写在新建的单独配置的那个config.js文件(打包不会发生变化的第三方库的配置文件)
plugins: [
    new Webpack.DllPlugin({
        name: '[name]',
        path: path.resolve(__dirname, 'dll/[name].manifest.json')
    })
]
注意点: 这里的name必须和library一致

2.4告诉webpack去哪里查找动态库
在打包的时候如何webpack回到指定的映射文件中查找对应的动态库,
找打了那么就不会重新打包动态库中的内容了, 如果找不到才会重新打包
(以下配置写在原来的配置文件中)
new Webpack.DllReferencePlugin({
    manifest: path.resolve(__dirname, 'dll/vendors.manifest.json')
})

总的来说,通过2.3和2.4后,如果我们在index.js里面引入了打包过的第三方库
我们的index.html中也不会即引入那个打包了多个库的文件,
又引入通过代码分割打包的那个文件(index.js引入的库会通过代码分割打包一个文件,前面学的)

3.在来总结一下这四步
3.1新建一个配置文件, 专门用于打包不会变化的第三方库
3.2在打包项目的配置文件中, 通过add-asset-html-webpack-plugin将提前打包好的库插入到html中
3.3在专门打包第三方的配置文件中添加生成清单配置
3.4在打包项目的配置文件中, 告诉webpack打包第三方库的时候先从哪个清单文件中查询,
如果清单包含当前用到的第三方库就不打包了. 因为已经在html中手动引入了

4.动态链接库的优势
4.1不用手动插入
4.2所有第三方库只会被打包一次(所以在后续开发时,这些固定的库就不会被打包了,打包的只是那些变化的了)

5.当前动态链接库存在的问题
如果我们提前打包生成了多个文件和清单, 那么需要手动增加插入的文件和查询的清单
比如现在我们将jquery打包到一个
将另一个库打包到另一个文件,那么我们需要写多个清单和add-asset-html-webpack-plugin

6.如何解决
通过NodeJS代码动态添加
6.1.const plugins=[];//将以前的那些plugin写到一个数组

6.2动态获取dll目录下的js和json文件,分别设置

const dllPath = path.resolve(__dirname, 'dll');
const files = fs.readdirSync(dllPath);
files.forEach(function (file) {
   if(file.endsWith(".js")){
       plugins.push(new AddAssetHtmlPlugin({
            //动态添加到
           filepath: path.resolve(__dirname, 'dll', file)
       }));
   }else if(file.endsWith(".json")){
       plugins.push(new Webpack.DllReferencePlugin({
           manifest: path.resolve(__dirname, 'dll', file)
       }));
   }
});
-->
</body>

15 .happypack

<body>
<!--
1.什么是HappyPack?
默认情况下webpack打包项目是单线程的, 为了提升打包速度, 充分发挥多核 CPU 电脑的威力
我们可以通过HappyPack让webpack实现多线程打包

2.HappyPack使用
https://www.npmjs.com/package/happypack

2.1 npm install --save-dev happypack
2.2 引入const HappyPack = require('happypack');
2.3 将以前打包js的规则改为以下
{
    test: /\.js$/,
    exclude: /node_modules/,
    use: 'happypack/loader?id=js'
},
2.4 将以前打包js的规则放在plugin数组里面
new HappyPack({
        id: 'js',
        use: [{
            test: /\.js$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            options: {
                ... ...
            }
        }]
    })
-->
</body>

16.打包多个文件

<body>
<!--
0.需求利用webpack打包生成两个页面
一个页面叫做index, 一个页面叫做detail

1.如何打包多也应用?
1.1有多少个界面就指定多少个入口, 并给不同的入口指定不同的名称
entry: {
    index: './src/js/index.js',
    detail: './src/js/detail.js',
}
1.2有多少个界面就创建多少个HtmlWebpackPlugin, 并给不同的界面配置不同的名称

1.3在HtmlWebpackPlugin中通过chunks属性告知需要插入到当前界面的文件
new HtmlWebpackPlugin({
        // 指定打包的模板, 如果不指定会自动生成一个空的
        template: './src/index.html',
        filename: 'index.html',
        chunks: ['index', 'vendors~index']
        //在index.html中和index有关的才引入,不然所有机的js,css文件都会给你引进去
    }),
    new HtmlWebpackPlugin({
        // 指定打包的模板, 如果不指定会自动生成一个空的
        template: './src/index.html',
        filename: 'detail.html',
        chunks: ['detail', 'vendors~detail']
    }),
-->
</body>

18. 打包多页应用优化

<body>
<!--
1.当前打包多页面应用存在的问题
1.1有多少个界面就要编写多少个入口
1.2有多少个界面就要创建多少个HtmlWebpackPlugin
   并且每个HtmlWebpackPlugin中的配置都不一样

2.如何解决以上问题
2.1入口还是必须手动指定, 但是创建多少个HtmlWebpackPlugin和
如何配置HtmlWebpackPlugin可以通过代码动态生成
也就是原理和动态创建AddAssetHtmlPlugin/DllReferencePlugin一样
如下
2.1.1将以前直接暴露出去的对象赋值给config
const config ={};
2.2.2 通过函数动态添加plugins
config.plugins = makePlugins(config);
2.2.3 创建生成plugins的函数
function makeplugins(config){
    // console.log(Object.keys(config.entry));提取对象的key

    Object.keys(config.entry).forEach(function (key) {
        plugins.push(new HtmlWebpackPlugin({
            // 指定打包的模板, 如果不指定会自动生成一个空的
            template: './src/index.html',
            filename: key + '.html',
            chunks: [key, 'vendors~'+key]
        }));
    });
}
2.2.4 暴露
module.exports = config;
-->
</body>

19.bundle-analyzer(可视化分析)

<body>
<!--
1.什么是webpack-bundle-analyzer?
webpack-bundle-analyzer是一个可视化的打包优化插件
webpack-bundle-analyzer会将打包的结果以图形化界面的方式展示给我们
从webpack-bundle-analyzer生成的图形化界面中我们可以很清楚的知道
模块之间的依赖关系
模块大小
模块有没有重复打包, 重复引用等
从而针对性的对我们的代码进行优化
2 使用
2.1 npm install --save-dev webpack-bundle-analyzer
2.2 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
2.3 new BundleAnalyzerPlugin()
-->
</body>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容