webpack入门、常用配置以及打包优化

WEBPACK

一、从0搭建自己的webpack开发环境
1.什么是Webpack
  • 静态模块打包器
  • 功能:
    • 代码转换;
    • 文件优化;在生产环境不会压缩JS、CSS…
    • 代码分割;提取多个页面的公共代码,提取首屏不需要执行部分让其异步加载
    • 模块合并;模块化的项目里会有多个模块和文件,需要构建功能把模块分类合并成一个文件
    • 自动刷新;监听本地更改并刷新页面
    • 代码校验;提交到git仓库前校验代码
    • 自动发布;自动构建线上发布代码并传输给发布系统
  • webpack命令:
    • 查看版本号:npx webpack -v
    • 安装指定版本:webpack@3.12.0 webpack-cli
    • 开启文件监听模式:webpack --watch (消耗性能,如果想提升开发速度,完全可以使用webpack-dev-server)
2.初始化项目
  • npm init -y // 生成package.json文件
  • npm install webpack webpack-cli --save-dev // 生成node_modules文件夹
  • webpack-cli --mode 可以解析传递参数
3.Webpack快速上手
  • 打包:
    • webpack webpack-cli // 默认读取根目录下的src文件夹
    • npx webpack
  • 开发环境development && 生产环境 production;可以在package.json中进行脚本配置
  • 打包入口和出口的个性化配置,webpack.config.js
  • 配置拆分:通过参数判断当前环境,加载指定配置文件;
    • 合并配置文件:npm install webpack-merge
  • 生产环境默认打包配置

小记

  • hash命名文件在webpack中的几个区别:
    • hash:每次打包都会更改文件名,
    • chunkhash:每个入口对应chunk,会根据入口文件中的更改内容决定独立打包某个入口所对应的文件;
    • contenthash:根据文件内容是否变化来决定是否打包该文件;
  • mode取值,会将process.evn.NODE_ENV的值设置为production || development
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r3w4L8pB-1582959864761)(./static/process.env.png)]
4.Webpack-dev-server

启动本地服务,使用webpack-dev-server,npm install webpack-dev-server在内存中打包,不会产生实体文件;
devServer配置;

5.打包html插件

使用html-webpack-plugin自动生成html文件并且引入打包后的js内容;

6.清空打包结果

使用clean-webpack-plugin ,在每次打包之前都清除dist文件下的目录;

二、 Webpack中必须要掌握的配置
  1. 前言:webpack默认配置(零配置),非常弱,灵活性差,所以需要掌握一些配置;
  2. 开发相关:
    •  sourceMap:源代码与打包后的代码的映射关系,通过sourceMap定位到源代码;在dev模式中,默认开启,[devtool](https://webpack.js.org/configuration/devtool/),线上不推荐开启;
      
    • WebpackDevServer:
      • 作用:提升开发效率的利器,每次改完代码都需要重新打包一次,打开浏览器,刷新一次,很麻烦。我们可以安装webpack-dev-server;
      • 原理:启动服务后,会发现dist目录没有了,这是因为devServer把打包后的模块不会放在dist目录下,而是放在内存中
      • 配置:通过devServer选项指定端口号(port)、内容存放目录(contentBase)、本地代理配置(proxy)等等…
  3. 解析CSS :需要强调一下loader的执行顺序,默认是从下往上执行,从右边向左边
    • css-loader:解析css语法
    • style-loader:将解析的css变成style标签,插入到页面中
  4. css预处理器 .scss node-sass sass-loader .less less-loader …
    • 安装:npm install node-sass sass-loader;
    • 配置:rules
// 注意在a.css文件中再通过@import引入a.sass文件的配置方式
use: ['style-loader', {
    loader: 'css-loader',
    options: { // 给loader传递参数
        importLoader: 1 // 代表后面参数: sass-loader
    }
}, 'sass-loader']
  1. css样式兼容自动填充前缀 附:查看css样式兼容性的网址

    • postcss-loader ,查找有兼容性要求的css属性
    • autoprefixer,自动填充ms-|| webpack-…前缀
    • 配置:
    {
        test: /\.css$/,
        use: [
            'style-loader'',
            'css-loader',
            'sass-loader',
            {
                loader: 'postcss-loader',
                options: { // 给loader传递参数
                    plugins: () => [
                        require('autoprefixer')({
                            overrideBrowserslist: ["last 2 versions", ">1%"]
                        })
                    ]
                }
            }
        ]
    }
    
    • mini-css-extract-plugin, 抽离css样式文件,抽离的好处是 css文件可以和js并行加载
  2. 解析图片+icon

    • file-loader,配置图片格式匹配
    {
        test: /\.(jpe?g|png|gif)$/,
        use:'file-loader'
    }
    
  3. js相关

    • @babel/core @babel/preset-env babel-loader,

      • 用法:babel-loader是webpack与babel通信的桥梁(不会把es6转es5) @bebel-preset-env负责es6->es5,
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
          loader: 'babel-loader',
          options: {
              presets: ["@babel/preset-env"]
          }
      }
      
      • @babel/polyfill的使用:
        在入口文件index.js中import
      import "@babel/polyfill"
      

      但是会导致bundle.js非常庞大,所以我们希望按需引入,useBuiltIns选项是babel7的新功能,告诉babel如何配置@babel/polyfill,具体配置见/root/.babelrc
      小记
      当我们开发组件库时、工具库时,polyfill就不适合了,因为polyfill是注入到全局变量window下,会污染全局环境;开发组件库时,推荐闭包方式:@babel/plugin-transform-runtime

      • 避免js代码 重用:@babel/plugin-transform-runtime
      • ts配置:@babel-preset-typescript
      type State = Readonly<typeof initState> // 把initState中的属性拿出来变成只读的
      
    • terser-webpack-plugin,压缩js文件

  4. react+vue…

  5. 多入口配置
    实践:入口配置为对象,出口配置多个HTMLWebpackPlugin,通过 chunks 属性定义好对应的入口文件

三、 Webpack打包优化(打包大小、打包速度、模块拆分)
1、压缩+删除无用代码;
2、Tree-shaking(webpack自带) && Scope-hoistiong
  • Tree-shaking
    • 作用:去除掉js无用代码;
    • 适用范围:默认只支持 es6语法,静态导入,只在生产环境使用;
    • 配置:
    optimization: {
        usedExports: true
    }
    
    • 需要注意的是:通过import引入的可执行文件代码,但是并未真实使用,需要在package.json中配置:“sideEffects”: true, l(注意该种办法的副作用:如果引入css文件:import ‘a.css’,也会被去除),可以根据需要指定文件类型:
      "sideEffects": [
        "**/*.css" // glob语法
      ]
    
  • Scope-hoistiong(自带)
    • 作用:由于webpack打包的每个模块都会生成一个函数,会导致内存过大,所以,引入scope-hoistiong,作用域提升,减少作用域
3、DllPlugin && DllReferencePlugin
  • DllPlugin 动态链接库 某种方法实现了拆分 bundles,同时还大大提升了构建的速度(对项目运行优化没有帮助)
    • 打包第三方库
    • 配置:/root/build/webpack.dll.js
      注:可以通过指定libraryTarget 来决定导出方式(导出方式即图中所示)
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YHjWWGjk-1582959864764)(./static/library_result.png)]
  • DllReferencePlugin 在项目中可以找到 上一步打包好的dll中的指定文件;
        new DllReferencePlugin({
        manifest: path.resolve(__dirname, '../dll/mainfest.json')
        })
    
4、代码分割
  • 代码分割:即第三方库抽离,不同于dll这个是做缓存:生产环境下,自动将第三方库进行抽离:optimization.splitchunks
  • 配置:/root/util/webpack.base.js -> optimization.splitChunks,可以通过参数指定什么情况下自动分割代码,

DllPlugin与Optimization.splitChunks的区别

区别比较是否优化页面加载速度?执行时机建议使用场景
DllPlugin构建之前抽离开发环境提升打包速度
Optimization.splitChunks编译过程中抽离生产环境分割第三方代码
5、动态加载;
  • 草案语法:import()
    • 使用:动态导入,可以实现代码分割,应用在类比、路由懒加载…;
    • 原理:JSONP;
    • 语法:返回值为Promise对象;
  • 为动态加载的文件更改文件名的配置:chunkFilename + 魔术字符串
6、热更新(模块热替换Hot Module Replacement);
  • 定义:模块热替换是Webpack提供的最有用的功能之一,它允许在运行时替换、添加、删除各种模块,而无需进行完全刷新重新加载整个页面;了解更多点击进入官网
  • 实现:
    • 保留在完全重新加载页面时丢失的应用程序的状态;
    • 只更新改变内容,节省开发时间;
    • 调整样式更加快速,几乎等同于在浏览器调试器中更改样式;
  • 配置:
    devServer: {
        hot: true
    }
    new webpack.NamedModulesPlugin()
    
  • 让js支持热更新:
    import sum from './sum'
    console.log(sum(1, 2))
    if (module.hot) { // 判断是否支持热更新
        module.hot.accept() // 当入口文件变化后重新执行当前入口文件,原理是监听到变化后,删除dom再重新将新的添加到文档中;
    }
    
    如果在项目中使用,不用单独配置,配置框架loader即可,
7、happypack;

happypack多线程打包,将不同的逻辑交给不同的线程来处理

8、CDN加载文件;
  • 意义:webpack打包出来的都会放到bundle.js(出口文件)中,bundle.js会非常庞大,所以我们引入CDN,拆分bundle.js
  • 使用:bootcnd,找到插件,复制script标签,粘贴进模板文件中,但是当文件较多时,不能都在index.html中引入,所以可以使用 add-asset-html-cdn-webpack-plugin 插件
    plugins: [
        new AddCdnPlugin(true, {
            'jquery': 'https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js'
        })
    ]
    
  • 配置:声明外部文件
    externals: {
        'jquery': '$' // 引入外部变量,在使用$时,是从外部引入的jq,不去打包代码中的jquery
    }
    
9、IgnorePlugin;

忽略import和require语法

10、noParse;

module.noParse,对类似jq这类依赖库,内部不会引用其他库,我们在打包的时候没有必要去解析,这样能够增加打包速率

noParse: /jquery/
11、resolve;
resolve: {
    extensions: [".js", ".jsx", ".json", ".css"],
    alias: {},
    modules: ['node_modules']
}
12、include/exclude;

在使用loader 时,可以指定哪些文件不通过loader,或者指定哪些文件通过loader

13、打包文件分析工具
四、原理
  1. 简单实现一个文件导入,代码转换:见/root/util/bundle.js
  2. 简单实现一个loader 官网描述
  3. 简单编写一个plugins 官网描述
    插件是可以作用在webpack打包的整个生命周期中,所以需要了解compiler钩子compilation钩子

原文链接及代码查看请进入github 如果喜欢,请动动您可爱的小手点亮star— ^.^

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值