webpack1升级webpack2

webpack2终于正式发布了。最近几天一直在调研webpack2的升级成本,因为公司的移动端使用的是webpack1,升级的目的也是为了之后pc端做一些铺路吧。

项目目录

Paste_Image.png

bulid目录

glup中的task配置,webpack环境配置,不同环境不同编译。支持热替换。

node_modules

这个不用说了吧。

src

主目录,也是需要编译的目录。里面的modules是react的代码,resources是静态文件,比如字体文件、图片、全局scss等

开始升级

看了一遍升级文档,然后一项项配置。每配置完一项之后都试着在本地环境去运行,看看有哪些错误,然后一个个解决。自动化工程我觉得就是在试错中才会成功。

resolveLoader

在webpack1中,resolveLoader配置root属性已经被modules所替换
webpack1版本:

resolveLoader: {
    root: path.join(rootPath, 'node_modules')
}

webpack2版本:

resolveLoader: {
    modules: ['node_modules']
}

module

module里面最主要的变化还是挺大的,这应该也是这次webpack团队的升级核心。

  1. 变化一,loaders属性被rules替换。
  2. 变换二,preLoaders被剔除,将在rules里面进行配置
  3. 变化三,loader不再支持缩写,如果想要支持缩写还得配置,这里不进行配置缩写项,因为我觉得没必要。
  4. 变化四,添加options属性。

webpack1代码如下

module: {
    // preLoaders属性将被剔除
    preLoaders: [{
        test: /modules\/\S*\.jsx?$/,
        loader: 'eslint',                      // loader将不支持简写而需要写成eslint-loader
        include: rootPath,
        exclude: /node_modules/
    }],
    // loaders属性将被rules替换
    loaders: [{
        test: /\.ejs$/,
        loader: 'ejs-loader'
    }, {
        test: /\.(jpe?g|png|gif)$/i,
        loader: 'url?limit=10000&name=images/[name].[hash:7].[ext]',
    }, {
        test: /\.(svg|woff2?|eot|ttf|otf)(\?.*)\S*$/,
        loader: 'url',
        query: {
            limit: 10000,
            name: 'fonts/[name].[hash:7].[ext]'
        }
    }]
}

webpack2代码如下

module: {
        rules:[
            {
                test: /modules\/\S*\.jsx?$/,
                loader: 'eslint-loader',
                include: rootPath,
                // enforce这个属性要注意一下,之前的preLoader被剔除了,但webpack2还是提供了代替方案。
                enforce: "pre",
                exclude: /node_modules/,
                options: {
                    formatter: require('eslint-friendly-formatter')
                }
            },
            {
                test: /\.ejs$/,
                loader: 'ejs-loader'
            },
            {
                test: /\.(jpe?g|png|gif)$/i,
                loaders: [{
                    loader: 'file-loader',
                    options: {
                        name: 'images/[name].[hash:7].[ext]'
                    }
                }, {
                    loader: 'image-webpack-loader',
                    options: {
                        mozjpeg: {
                            progressive: true,
                        },
                        gifsicle: {
                            interlaced: false,
                        },
                        optipng: {
                            optimizationLevel: 7,
                        },
                        pngquant: {
                            quality: '65-90',
                            speed: 4
                        }
                    }
                }],

            }, {
                test: /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/,
                loader: 'file-loader',
                options: {
                    name: 'fonts/[name].[hash:7].[ext]'
                }
            }
        ]
    },

可以看到webpack2新增enforce属性来代替preLoader。

loader options

webpack2配置项中eslint、postcss的这些原本属于loader里的属性会被移除,并且编译会报错!
比如我在webpack1中的配置是这样的

import webpack from 'webpack'
import autoprefixer from 'autoprefixer'
import precss from 'precss'
import postcssScss from 'postcss-scss'
import path from 'path'
import postcssImport from 'postcss-import'
const rootPath = path.join(__dirname, '..')

export default  {
    entry: {
        'app': [`${rootPath}/src/modules/main.jsx`],
    },
    resolve: {
        root: [`${rootPath}/src`, `${rootPath}/node_modules`],
        extensions: ['', '.js', '.jsx', '.css', '.scss', '.json']
    },
    resolveLoader: {
        root: path.join(rootPath, 'node_modules')
    },
    module: {
        preLoaders: [
            {
                test: /modules\/\S*\.jsx?$/,
                loader: 'eslint',
                include: rootPath,
                exclude: /node_modules/
            }
        ],
        loaders: [
            {
                test: /\.ejs$/,
                loader: 'ejs-loader'
            },
            {
                test: /\.(jpe?g|png|gif)$/i,
                loader: 'url?limit=10000&name=images/[name].[hash:7].[ext]',
            }, {
                test: /\.(svg|woff2?|eot|ttf|otf)(\?.*)\S*$/,
                loader: 'url',
                query: {
                    limit: 10000,
                    name: 'fonts/[name].[hash:7].[ext]'
                }
            }
        ]
    },
    // webpack2报错!!!
    eslint: {
        formatter: require('eslint-friendly-formatter')
    },
   // webpack2报错!!!
    postcss: function (webpack) {
        return {
            plugins: [
                postcssImport({
                    glob: true,
                    onImport: function (files) {
                        files.forEach(this.addDependency)
                    }.bind(this),
                    path: `${rootPath}/src`
                }),
                precss({
                    import: {
                        disable: true
                    }
                }),
                autoprefixer({ browsers: [ 'last 2 versions' ] }),

            ],
            parser: postcssScss
        }
    }
}

但webpack2中还是提供了响应的方法,就是将这些配置写到rule里的options之中。比如eslint-loader

rules:[{
    test: /modules\/\S*\.jsx?$/,
    loader: 'eslint-loader',
    include: rootPath,
    enforce: "pre",
    exclude: /node_modules/,
    // webpack1中的配置项需要写到这
    options: {
        formatter: require('eslint-friendly-formatter')
     }
}]

至于postcss之后我会说下遇到的坑。

postcss

前面已经说到loader options不能配置到config中,然后这个postcss还是挺特别的。因为我写到postcss-loader里面是不管用的。然后根据webpack2提供的插件LoaderOptionsPlugin我把postcss写进去,在local环境的时候,不使用extract-text-webpack-plugin分离css的情况下是编译成功的。代码如下:

var autoprefixer = require('autoprefixer');
var precss = require('precss');
var postcssScss = require('postcss-scss');
var postcssImport = require('postcss-import');
var sprites = require('postcss-sprites');
var sassyMixins = require('postcss-sassy-mixins');
export default  {
   ....
    plugins: [
      new webpack.LoaderOptionsPlugin({
          postcss: {
              plugins: [
                  postcssImport({
                  glob: true,
                  path: './src'
               }),
              sassyMixins(),
              precss(),
              autoprefixer({ browsers: [ 'last 2 versions' ] }),
          ],
          parser: postcssScss
         }
      })
       ...
    ]
}

extract-text-webpack-plugin

在这个插件中,webpack2也是改动较大的地方,它的参数变成了一个对象。
在webpack1中

const extractCSS = new ExtractTextPlugin('css/[name].min.[contenthash:8].css', {
    allChunks: false
})

webpack2

// new ExtractTextPlugin(options: filename | object)

new ExtractTextPlugin({
    id: '{string}',
    filename: '{string}' || function () {},
    allChunks: {bool},
    disable: {bool},
    ignoreOrder: {bool}
})

接着是loader的配置,在webpack1中,还是以参数的形式传递

const cssLoader = extractCSS.extract(
    'style-loader',
    `css-loader?sourceMap&minimize&modules&localIdentName=[name]__[local]___[hash:base64:5]&importLoaders=1!postcss-loader?sourceMap`
)
const globalCssLoader = extractCSS.extract(
    'style-loader',
    `css-loader?sourceMap&minimize&importLoaders=1!postcss-loader`
)

在webpack2中更变为object

const cssLoader = extractCSS.extract({
    fallback: 'style-loader',
    use: [{
        loader: 'css-loader',
        options: {
            sourceMap: true,
            minimize: true,
            modules: true,
            importLoaders: 1,
            localIdentName: '[name]__[local]___[hash:base64:5]'
        }
    }, {
        loader: 'postcss-loader'
    }]
})
const globalCssLoader = extractCSS.extract({
    fallback: 'style-loader',
    use: [{
        loader: 'css-loader',
        options: {
            sourceMap: true,
            importLoaders: 1,
            minimize: true
        }
    }, {
        loader: 'postcss-loader'
    }]
})

是不是很简单。但在这我又遭遇到了一个坑!那就是postcss问题,我在编译的时候postcss爆出一个错误,说是读不到配置文件。在google找一圈,他们给出的解决方案是用webpack2中的LoaderOptionsPlugin来解决,但我没解决成功,肯定是有哪些步骤出错了。
然后我在google的时候发现有人提到在根目录下创建一个postcss.config.js文件。根据postcss文档的提示,我推断了一下,postcss在运行的时候,先是会匹配它的options,但若没有匹配上,那么它就会去根目录去找postcss.config.js文件!之后,我把base里面的postcss配置都提出来放到根目录下,这样代码也解耦了一部分。
postcss.config.js

var autoprefixer = require('autoprefixer');
var precss = require('precss');
var postcssScss = require('postcss-scss');
var postcssImport = require('postcss-import');
var sprites = require('postcss-sprites');
var sassyMixins = require('postcss-sassy-mixins');
module.exports = {
    plugins: [
        postcssImport({
            glob: true,
            path: './src'
        }),
        sassyMixins(),
        precss(),
        autoprefixer({ browsers: [ 'last 2 versions' ] }),
    ],
    parser: postcssScss
};

试着编译一下,成功!

Paste_Image.png

总结

webpack1升级到webpack2其实挺简单的,并且成本很低。最后还是得编译的速度,打包的体积进行优化。在webapp中600K确实是非常大了,自家人用,加上gzip的话230K左右,用上cdn,大概在15KB这样。webpack2有个新特性,就是Tree Shaking,之后尝试下这个工具。对了,安利下yarn,安装包速度炒鸡快!并且和npm无痛切换,就是在linux安装麻烦了些!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容