Webpack面试题(二)

高级配置

多入口文件

(1)
common.js 修改入口

(2)
修改prod的output 设置动态属性名 后缀加上hash变量

(3)
common里的plugins实例要生成生成两个

chunks如果不写,这两个html默认就是把入口两个文件都引入 所以需要写一下 

抽离CSS文件

之前所有css都通过style-loader放进了style里 
但线上这样就不太好哈 还是得抽离一下
1.使用minicssextractplugin.loader加载
2.在plugins里抽离


3.在optimization里压缩
// 引入插件
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

// 增加 webpack 配置
    optimization: {
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
    },
抽离less同理


*抽离公共代码

在线上环境需要这么做
多个页面或者入口,如果引用了同一段代码,如上文的多页面例子中,index.js 和 other.js 都引用了 import './common.js' ,则 common.js 应该被作为公共模块打包。webpack v4 开始弃用了 commonChunkPlugin 改用 splitChunks ,可修改 build/webpack.prod.js 中的配置

同理,如果我们的代码中引用了 jquery lodash 等,也希望将第三方模块单独打包,和自己开发的业务代码分开。这样每次重新上线时,第三方模块的代码就可以借助浏览器缓存,提高用户访问网页的效率。修改配置文件,增加下面的 vendor: {...} 配置。
    optimization: {
        // 分割代码块
        splitChunks: {
                  chunks: 'all',
            /**
             * initial 入口 chunk,对于异步导入的文件不处理
                async 异步 chunk,只对异步导入的文件处理
                all 全部 chunk
             */

            // 缓存分组
            cacheGroups: {
                // 第三方模块
                vendor: {
                                        name:'vendor'//chunk名称
                    priority: 1, // 权限更高,优先抽离,重要!!!
                    test: /node_modules/,
                    chunks: 'initial',
                    minSize: 0,  // 大小限制
                    minChunks: 1  // 最少复用过几次
                },

                // 公共的模块
                common: {
                                        name:'common'//chunk名称 
                    chunks: 'initial',
                    minSize: 0,  // 公共模块的大小限制
                    minChunks: 2  // 公共模块最少复用过几次
                }
            }
        }
    }
对应的,可以在common里,规定各入口文件可以使用哪些模块:

chunk 就是块 在entry里生成了两个块 在splitChunks里又生成了两个块

懒加载

webpack 支持使用 import(...) 语法进行资源懒加载。安装 npm i @babel/plugin-syntax-dynamic-import -D 然后将插件配置到 .babelrc 中。

新建 src/dynamic-data.js 用于测试,内容是 export default { message: 'this is dynamic' } 。然后在 src/index.js 中加入
setTimeout(() => {
    import('./dynamic-data.js').then(res => {
        console.log(res.default.message)  // 注意这里的 default
    })
}, 1500)
在异步加载的时候,也产生了一个chunk  dynamic-data.js 的内容被打包一个单独的文件中。

其他的小知识点:
处理JXS
处理VUE用vue-loader

 三、概念问题

module chunk bundle区别

module 
一切皆模块 不管什么文件 所有源码文件都是module
chunk
多模块的合成  如entry  splitChunk会包含多个模块 是还没有整理的输出

bundle
最终的输出文件 可以理解为chunk整理后的输出

性能优化

优化打包速度



1.给babel-loader开启缓存

2.忽略无用模块
比如一个模块支持好多语言,我们只想要中文
例子:
一个日期插件 非常大

可以通过 ignorePlugin 插件忽略 locale 下的语言文件,不打包进来。
    plugins: [
        new webpack.IgnorePlugin(/\.\/locale/, /moment/), 
        // 忽略 moment 下的 /locale 目录
之后再手动加载需要的语言包:
import moment from 'moment'
import 'moment/locale/zh-cn' // 手动引入中文语言包
moment.locale('zh-cn')
const r = moment().endOf('day').fromNow()
console.log(r)
3.避免重复打包
两者的区别是:
4.*happyPack
JS是单线程,开启多进程打包,适合多核CPU
,小项目使用反而会变慢。只有项目较大,打包出现明显瓶颈时,才考虑使用 happypack 。

5.ParalleUglifyPlugin 
开启多进程压缩
6.自动刷新(不能用在生产环境里)
一般情况下没得用
整个网页全部刷新,速度较慢,而且状态会丢失

7.热更新(不能用在生产环境里)
新代码生效,网页不刷新,状态不丢失
在devServer里配置 hot:true 但是需要自己配置

8.DllPlugin(不能用在生产环境里)
动态链接库插件
webpack已经内置了
先把vue react做一个预打包:
之后就不再重新打包,直接来使用:

***产出代码

  • 小图片base64编码 就不做网络请求了
  • bundle+hash 代码没有变化 hash就不会有变化 不需要重新加载
  • 懒加载
  • 提取公共代码splitChunks
  • IngorePlugin
  • 使用CDN加速
  • *使用production 
  • *Scope Hosting

production 

就是prod.js里的mode:’production‘ 就是线上环境的配置
  • 自动开启压缩代码 是代码体积更小 线上速度更快
  • Vue React等会自动删掉调试代码(如开发环境下的warning)
  • 启动Tree-Shaking**

Tree-Shaking

可以想象成摇树 把没有用的树叶子摇下去 production会自动做这些工作
必须用es6 module才能让Tree-Shaking生效  commonjs不行
因为这是因为 require 是动态引入,无法在编译时判断哪些功能被使用。而 import 是静态引入,编译时即可判断依赖关系。

Scope Hosting

默认的打包结果,每个文件生成一个函数 体积大 

使用Scope Hosting   把多个函数合成一个函数  创建的函数作用域更少:

配置方法:
引用插件 开启插件 就行了

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务