资讯专栏INFORMATION COLUMN

webpack v2升级踩坑笔记

JayChen / 2901人阅读

摘要:从再到目前当红明星,前端模块打包技术日新月异,在今年月份和月份左右接连更新了和版本为了减少冗余模块,缩减文件大小,中也加入了关于的特征,可以查看知乎如何评价新引入的代码优化技术的讨论。

从Grunt->gulp->webpack,再到目前当红明星rollup,前端模块打包技术日新月异,webpack在今年1月份和6月份左右接连更新了v2和v3版本,为了减少冗余模块,缩减bundle文件大小,webpack v2中也加入了tree-shacking,关于tree-shacking的特征,可以查看知乎如何评价 Webpack 2 新引入的 Tree-shaking 代码优化技术?的讨论。

webpack在推出 v2之后迅速推出了v3版本,前段时间在知乎看到webpack作者LarkInn(他已经入驻sf)说后续会维持一个更快、一致和更稳定的发布周期点这,难道要步Angular的后尘,作为吃瓜群众表示很震惊,因为目前自己这边项目webpack还停留在1.x版本,鉴于减少日后升级难度的想法,包括后续要做代码和流程优化,我将webpack升级到了v2版本,在这主要想把这个升级过程遇到的一些问题分享出来,也方便大家踩坑。

1. 更新版本号

我能想到最简单粗暴的做法就是直接把版本号改了下载新包看下会发生什么。使用npm info webpack查看了一下版本的发布信息,我更新到2.6.1版本,也是3.0前的最后一个版本,
期待一大堆报错,很尴尬,发现webpack仍然使用1.x版本工作,也就是说包并没有更新到,查了一下发现可能缓存造成的,使用npm cache clean但貌似也不管用,索性直接把node_module删除了,重新安装了一下模块,打包,果然报错了:

2.resolve变更

报错信息:

throw new WebpackOptionsValidationError  
configuration.resolve.extensions[0] should not be empty
...    

提示是resolve.extensions写法有问题,查看了一下extensions文档

This option no longer requires passing an empty string. 不再支持空字符的写法了。

webpack1.x写法:

    resolve: {
        root: ....
        extensions: ["", ".js", ".jsx", ".json"]
    },

webpack2写法:

    resolve: {
        root: ....
        extensions: ["*", ".js", ".jsx", ".json"]
    },

报错信息:

configuration.resolve has an unknown property "root". These properties are valid:
...

原来root写法也变了,root放在modules里了。

    resolve: {
        modules: [
            path.resolve(__dirname, "src"), "node_modules"
        ]
    }
}
3.loaders => rules
 configuration.module.rules[0].use should be one of these: ...

接下来应该就是一堆loader写法有问题,loader已经全部改成了rules的写法,并且为了更加严谨?之前省略的loader后缀也得加上。由于webpack2会自动给加载json文件,所以json-loader也就不再需要了,查看这里。

webpack1.x写法:

webpackConfig.module.loaders = [{
    test: /.(js|jsx)$/,
    exclude: /node_modules/,
    loader: "babel",
    query: ""
}, {
    test: /.json$/,
    loader: "json"
}]

webpack2.x写法:

webpackConfig.module.loaders = [{
    test: /.(js|jsx)$/,
    exclude: /node_modules/,
    use: [{
        loader: "babel-loader",
        query: {
            cacheDirectory: true,
            plugins: [..plugins],
            presets: [..presets]
        }
    }]
}]

css-loader,style-loader的配置:

webpack1.x写法:

webpackConfig.module.loaders.push({
    test: /.css$/,
    exclude: null,
    loaders: [
        "style",
        "css?modules&importLoaders=1&sourceMap&minimize",
        "postcss?pack=default"
    ]
})

webpack2.x写法:

webpackConfig.module.rules.push({
    test: /.css$/,
    exclude: null,
    use: [
        "style-loader",
        {
            loader: "css-loader",
            opitions: {
                modules: true,
                sourceMap: true,
                minimize: true,
                importLoaders: 1
            }
        },
        "postcss-loader"
    ]
})

==注意== 这里css-loder的minimize默认是不开启的,建议开启压缩可以缩小文件大小。babel-loader的cacheDirectory开启缓存可以加速编译过程。

4.extract-text-webpack-plugin

修改原来的ExtractTextPlugin插件配置,对css文件进行处理,发现报如下错误:

报错:

 throw new Error("Chunk.entry was removed. Use hasRuntime()");

google了一下发现是当前版本(1.0.1)已经不适用, 升级到2.0。

webpackConfig.module.rules.push({
    test: /.css$/,
    use: extractText.extract({
        use:[
        { loader: "style-loader" },
        {
            loader: "css-loader",
            options: {
                sourceMap: true,
                minimize: true,
                importLoaders: 1,
                modules: true
            }
        },
        { loader: "postcss-loader" }
    ] })
})

const extractText = new ExtractTextPlugin({
  filename: "styles/[name].[contenthash].css",
  allChunks: true,
  disable: __DEV__
})

webpackConfig.plugins.push(extractStyles)

5.postcss-loader

postcss-loader插件配置会麻烦一些,有两种方法:
一种是新建postcss.config.js文件

module.exports = {
    plugins: [
        require("autoprefixer")({ /* ...options */ })
    ]
}

另一种:
在webpack.config.js使用LoaderOptionsPlugin

webpackConfig.plugins.push(
    new webpack.LoaderOptionsPlugin({
        options: {
            postcssLoader: () => {
                require("autoprefixer")(/* ...options */ )
            }
        }
    })
)
6.loaderUtils Warning

DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see https://github.com/webpack/lo...

貌似是loader-utils模块引起的,没有太明白问题出在哪,issues地址,我在webpack.config.js在加上下面代码解决了。

process.noDeprecation = true
升级总结

v1.x的时候大家都在吐槽webpack文档问题,v2文档确实提升不少,包括这次的升级如果跟着指南走,基本不会出什么大问题,只是中途在配置ExtractTextPlugin、postcss插件时折腾了一些时间。完成这次的升级后,后续准备对流程再进一步的优化,缩减打包时间、减少bundle大小等。
这里推荐一款插件webpack-visualizer-plugin,可以将项目的打包情况可视化,清楚了解到每个模块的大小、占比,方便后续的优化。

如果对v2版配置还有问题的同学,可以查看我之前的一个v3.1版本的webpack.config.js。

附:
1.webpack v1至v2升级指南
官方webapck 1->2升级guides
另一位同学翻译的升级指南中文版
2.几篇关于升级优化的好文章:
Boost webpack build performance | Optimising webpack build performance | Webpack 构建性能优化探索
webpack2 终极优化
3.关于webpack的好文章集合(awesome-webpack)
搜罗一切webpack的好文章好工具

(ps:第一次写关于webpack的文章,不免有误,请及时斧正)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83978.html

相关文章

  • webpack3 升级 webpack4踩坑记录

    摘要:本篇不包含所有坑,暂时只记录自己踩到的部分坑一安装安装最新版本安装新增依赖这个在中,本身和它的是在同一个包中,中将两个分开管理。我记录下自己更新这个的过程,以下前半部分可以直接跳过。以下记录踩坑过程。 本篇不包含所有坑,暂时只记录自己踩到的部分坑 一.安装 安装webpack4最新版本 npm install --save-dev webpack@4 安装新增依赖 webpack-c...

    马忠志 评论0 收藏0
  • [笔记]React+Cordova踩坑

    摘要:之前做过一点前端的小项目所以前端还算熟练因为最近在准备所以想能不能写一个背单词软件正好这学期有个开发课,就用来当大作业了前端后端如何在下调试当然是代理啦在之前两个项目中为了不用代理强行在后端启用了事实证明这是个愚蠢的决定因为完全不适合做后端 之前做过一点前端的小项目所以前端还算熟练因为最近在准备GRE所以想能不能写一个背单词软件正好这学期有个Android开发课,就用来当大作业了 前端...

    shadajin 评论0 收藏0
  • 我的WebPack入门(一)

    摘要:因为这里我的文件夹名字起的叫,所以默认生成的中的就是,而是关键字会导致,只需要打开把随便改一下即可。其实关于都还有很多参数配置和方法,不过对于入门,在上面这些东西搞明白后,就已经可以跑起来一个简单的流程了。 WebPack已经火了好久,几乎已经成为一个前端的必备技能,先翻译官网两句话。 WebPack是一个灵活的、可扩展的、公平的、可用于生产环境的、开源的模块打包器。 WebPack...

    liuchengxu 评论0 收藏0
  • vue-cli + es6 多页面项目开发及部署

    摘要:前段时间项目组计划快速开发一个新的项目,开发那边提供壳子和部分系统级功能,所有的页面由完成,考虑兼容性安卓及。后面会继续优化,先把目前的基本部署方式记录下来。 前段时间项目组计划快速开发一个新的App项目,App开发那边提供壳子和部分系统级功能,所有的页面由h5完成,考虑兼容性安卓4.1及ios7.1。全新的项目,没有历史包袱,就尝试了新的开发模式,采用了webpack + vue-c...

    felix0913 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<