前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >升级你的webpack(下)-- webpack入门教程(三)

升级你的webpack(下)-- webpack入门教程(三)

原创
作者头像
前端林子
修改2018-09-15 16:36:25
3.3K1
修改2018-09-15 16:36:25
举报
文章被收录于专栏:前端技术总结前端技术总结

背景介绍:

我负责的一个前端项目之前用到的是webpack1,现需要升级到webpack4,特此记录下升级过程中有一些配置和需要注意的问题,具体会介绍:

(1) 需要的node环境的升级

(2) mode参数切换开发模式还是生产模式

(3) 移除了CommonsChunkPlugin,改用了optimization属性进行更加灵活的配置

(4) 用新的CSS文件提取插件mini-css-extract-plugin,替换extract-text-webpack-plugin

由于篇幅较长,分为上下两篇介绍,本文主要介绍后面两点,关于前面两点的介绍,请移步升级你的webpack(上)-- webpack入门教程(二)

1.使用optimization,替代了CommonsChunkPlugin

1.1 持久化缓存

webpack需要使用hash来做静态资源的更新,文件名的hash值目前有三种计算hash的方式:[hash]、[chunkhash]以及[contenthash]。

区别:

[hash]:每次webpack在编译的过程中会生成唯一的hash值,项目中任何一个文件改动后就会被重新创建,然后webpack会计算新的hash值。简单来说,hash是跟整个项目的构建相关,每一次构建就生成一个hash值,即使文件内容没有改变。

[chunkhash]:根据模块计算出来的hash值,所以某个文件的改动只会影响自己的hush值,而不会影响到其他文件的hash值。

[contenthash]:由文件内容产生的hash值,内容不同产生的contenthash值就不一样。

如果项目中是把所有的内容都打包成同一个文件,那么[hash]就足够了。而如果项目中涉及到拆包、分模块进行加载等,那么需要用到[chunkhash],来保证每次更新后,只有改变的相关文件的hash值发生改变。

代码语言:javascript
复制
module.exports = {
    entry: {
        index: [
            path.resolve(__dirname, './modules/index.js')
        ]
    },
    output: {
        path: path.resolve(__dirname, '../../app/public/v2'), 
        filename: 'js/[name].[chunkhash:8].js',
    }
}

上述代码的意思是:以index.js为入口文件,将所有的代码全部打包到一个文件名为index.xxxx.js,并放到app/public/v2/js目录下,这样每次更新代码时会生成新的命名文件了。

但这样只能应付简单的场景,在大型多页面应用中,往往需要对页面进行优化,涉及拆包、分模块加载:

(1)分离业务代码和第三方的代码:之所以将业务代码和第三方代码分离出来,是因为业务代码更新频率高,而第三方代码更新迭代速度慢,所以我们将第三方代码(库,框架)进行抽离,这样可以充分利用浏览器的缓存来加载第三方库。

(2)按需加载:比如在使用 react-router 的时候,当用户需要访问到某个路由的时候再去加载对应的组件,那么用户没有必要在一开始的时候就将所有的路由组件下载到本地。

(3)在多页面应用中,我们往往可以将公共模块进行抽离,比如 header, footer 等等,这样页面在进行跳转的时候这些公共模块因为存在于缓存里,就可以直接进行加载了,而不是再进行网络请求了。

那么如何进行拆包,分模块进行加载呢?

在webpack4之前,可以使用webpack 内置插件:CommonsChunkPlugin。从webpack4开始,optimization

替代了CommonsChunkPlugin插件,改用optimization属性进行更加灵活的配置。

1.2 使用optimization属性,替代CommonsChunkPlugin

每个配置项的作用:

-- minSize 

分离前的最小块文件大小,单位为字节

-- minChunks

分离前该块被引入的次数

-- maxInitialRequests

一个入口文件可以并行加载的最大文件数量

-- maxAsyncRequests

内层文件(第二层)按需加载时最大的并行加载数量

-- name

用以控制分离后代码块的命名,若不存在则为  [来源]~[入口的key值].js 的格式

-- automaticNameDelimiter

修改上文中的 “~” ,  若改为: “-” 则分离后的js默认命名规则为 [来源]-[入口的key值].js

-- test

用来控制哪些模块被缓存组选择,test: /node_modules/  即为匹配相应文件夹下的模块

-- cacheGroups

缓存组,其实就是存放分离代码块的规则的对象。如果不希望使用默认配置,可以通过splitChunks.cacheGroups进行配置,cacheGroup中priority 为分离规则的优先级,优先级越高,则优先匹配。

-- chunks

匹配的块的类型:initial(初始块),async(按需加载的异步块),all(所有块)

-- priority

这个配置很重要,即便是所有配置项都写好了,优先级不够,或者优先级设置不正确,也得不到相应的结果。当需要优先匹配缓存组的规则时,priority需要设置为正数,当需要优先匹配默认设置时,缓存组需设置为负数,0为两者的分界点。

更多的配置项可参看webpack官方文档以下是optimize.splitChunks 中的一些配置参考:

代码语言:javascript
复制
module.exports = {
    optimization: {
        runtimeChunk: {
            name: 'manifest'
        },
        //webpack4不再需要UglifyJsPlugin,设定optimization.minimizer为true即可
        //production mode下面自动为true
        minimizer: true,
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            name: false,
            cacheGroups: {
                vendor: {
                    name: 'vendor',
                    chunks: 'initial',
                    priority: -10,
                    reuseExistingChunk: false,
                    test: /node_modules\/(.*)\.js/
                },
                //将多个css chunk合并成一个css文件
                styles: {
                    name: 'styles',
                    test: /\.(scss|css)$/,
                    chunks: 'all',
                    minChunks: 1,
                    reuseExistingChunk: true,
                    enforce: true
                }
            }
        }
    }
}

说明:

(1) CommonsChunkPlugin需要通过配置两次new webpack.optimize.CommonsChunkPlugin来分别获取vendor和manifest的通用chunk方式已经做了整合, 直接在optimization中配置splitChunks和runtimeChunk即可 ,提取功能也更为强大。

(2) runtimeChunk可以配置成true、single或者对象,用于自动计算当前构建的一些基础chunk信息,类似之前版本中的manifest信息获取方式。

(3) webpack.optimize.UglifyJsPlugin现在不需要了,只需要使用optimization.minimizer为true即可,production mode下面自动为true,当然如果想使用第三方的压缩插件也可以在optimization.minimizer的数组列表中进行配置,例如这样配置:

代码语言:javascript
复制
//在optimization.minimizer的数字列表中配置,使用第三方的压缩插件
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

config.optimization = {
    minimizer: [
        new UglifyJsPlugin({
            cache: true,
            parallel: true
        }),
        new OptimizeCSSPlugin({
            cssProcessorOptions: {
                autoprefixer: { disable: true },
                discardComments: {
                    removeAll: true,
                },
                canPrint: true
            }
        })
    ],
};

2.使用mini-css-extract-plugin,替代了extract-text-webpack-plugin

优点:

没有重复编译,性能比原来要好

异步加载,当js文件被异步加载时,需要的css文件也会自动加载

因为只针对css文件,所以自动带了一些优化,比如在mode:production时,自动minify

webpack1使用extract-text-webpack-plugin,基本配置如下:

代码语言:javascript
复制
//webpack1用extract-text-webpack-plugin:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
    module: {
        loaders: [
            {
                test: /\.less$/,
                loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
            },
            {
                test: /\.css$/,
                loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader")
            },
        ]
    },

    plugins: [
        new ExtractTextPlugin("css/[name].[chunkhash].css"),
    ]
}

webpack4使用mini-css-extract-plugin,基本配置如下:

代码语言:javascript
复制
//webpack4用mini-css-extract-plugin:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
    module: {
        rules: [
            {
                test: /\.less$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'less-loader'
                ]
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].[chunkhash].css"
        }),
    ]
}

3.小结

本文详细介绍了项目中从webpack1升级到webpack4时一些需要注意的配置,如有问题,欢迎指正。

以下是webpack系列的往期文章:

超详细!webpack入门教程(一)

升级你的webpack(上)-- webpack入门教程(二)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍:
  • 1.使用optimization,替代了CommonsChunkPlugin
    • 1.1 持久化缓存
      • 1.2 使用optimization属性,替代CommonsChunkPlugin
      • 2.使用mini-css-extract-plugin,替代了extract-text-webpack-plugin
      • 3.小结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档