本文github倉庫:https://github.com/Rynxiao/webpack2-learn

從v1遷移到v2

1. 配置類型

在webpack1的時候,主要是通過導(dǎo)出單個object來進(jìn)行配置。例如下面的配置:

// webpack1 導(dǎo)出方式module.export = {
    entry : 'app.js',
    output : { */... */},
    /* ... */};

而在webpack2中,則有三種方式來靈活配置,可以針對不同的場景。

1.1 通過不同環(huán)境變量導(dǎo)出不同的配置文件

// 可以有兩種方式傳遞當(dāng)前值,一種是簡單傳遞字符串,另外一種則是傳遞一個對象// 例如: webpack --env production 控制臺打印的就是 'production',是一個字符串// 而當(dāng)這樣調(diào)用時:webpack --env.production --env.size 60,控制臺打印的就是 { production : true, size : 60 }var path = require('path'),
    webpack = require('webpack'),
    UglifyJsPlugin = new webpack.optimize.UglifyJsPlugin(),
    plugins = [];module.exports = function(env) {

    console.log(env);
  
    if (env === 'production') {
        plugins.push(UglifyJsPlugin);
    }

    return {
        entry : path.resolve(__dirname, 'js/app.js'),
        output : {
            path : path.resolve(__dirname, 'build'),
            filename : '[name].bundle.js'
        },
        module : {
            rules : [                { 
                    test : /\.js|\.jsx$/, 
                    loader : 'babel-loader', 
                    options : {
                        presets : ["es2015", "react"]                    } 
                },
                { 
                    test : /\.css$/,
                    use : ['style-loader', 'css-loader']                },
                {
                    test : /\.less$/,
                    use : ['style-loader', 'css-loader', 'less-loader']                }
            ]        },
        plugins : plugins    };}// 在package.json中配置兩個命令{
    "dev" : "webpack",
    "build" : "webpack --env production"}

具體的生產(chǎn)環(huán)境構(gòu)建方式可以參看官網(wǎng)production

1.2 通過promise方式導(dǎo)出配置文件

這種方式的應(yīng)用場景是在某些情況下,我們暫時拿不到配置文件所需要的配置參數(shù),比如需要配置的文件名等等,或許這是一個異步的操作,通過promise方式可以使我們在異步操作之后得到配置變量,然后再執(zhí)行配置文件。

// 在這種情況下,1秒之后會返回配置文件并且執(zhí)行var path = require('path');module.exports = () => {
    return new Promise((resolve, reject) => {
        console.log('loading configuration ...');
        setTimeout(() => {
            console.log('loading completed!');
            resolve({
                entry : path.resolve(__dirname, 'js/app.js'),
                output : {
                    path : path.resolve(__dirname, 'build'),
                    filename : '[name].bundle.js'
                },
                module : {
                    rules : [                        { 
                            test : /\.js|\.jsx$/, 
                            loader : 'babel-loader', 
                            options : {
                                presets : ["es2015", "react"]                            } 
                        },
                        { 
                            test : /\.css$/,
                            use : ['style-loader', 'css-loader']                        },
                        {
                            test : /\.less$/,
                            use : ['style-loader', 'css-loader', 'less-loader']                        }
                    ]                },
            });
        }, 1000);
    });}

1.3 同時打包多份配置文件

webpack1時只能導(dǎo)出單份配置文件,在webpack2中可以同時打包多份配置文件,意味著可以為多個入口文件打包,在多頁面打包的時候,就再也不需要為在每一個單獨的頁面執(zhí)行打包命令了。

// config-amd.jsvar path = require('path');module.exports = {
    entry : path.resolve(__dirname, 'js/app.js'),
    output : {
        path : path.resolve(__dirname, 'build'),
        filename : '[name].amd.js',
        libraryTarget : 'amd'
    },
    module : {
        rules : [            { 
                test : /\.js|\.jsx$/, 
                loader : 'babel-loader', 
                options : {
                    presets : ["es2015", "react"]                } 
            },
            { 
                test : /\.css$/,
                use : ['style-loader', 'css-loader']            },
            {
                test : /\.less$/,
                use : ['style-loader', 'css-loader', 'less-loader']            }
        ]    }};// config-commonjs.jsvar path = require('path');module.exports = {
    entry : path.resolve(__dirname, 'js/app.js'),
    output : {
        path : path.resolve(__dirname, 'build'),
        filename : '[name].commonjs.js',
        libraryTarget : 'commonjs'
    },
    module : {
        rules : [            { 
                test : /\.js|\.jsx$/, 
                loader : 'babel-loader', 
                options : {
                    presets : ["es2015", "react"]                } 
            },
            { 
                test : /\.css$/,
                use : ['style-loader', 'css-loader']            },
            {
                test : /\.less$/,
                use : ['style-loader', 'css-loader', 'less-loader']            }
        ]    }};// webpack.config.jsvar configAmd = require('./config-amd.js'),
    configCommonjs = require('./config-commonjs.js');module.exports = [
    configAmd,
    configCommonjs
]

2. resolve相關(guān)

2.1 extensions 后綴擴展

在webpack2中,不需要默認(rèn)寫一個空字符串,如果沒有配置這個選項,則默認(rèn)的后綴名是['.js', '.json'],這樣可以在需要用到import 'some.js'的時候直接寫import 'some'就好。

如果不想開啟自動后綴,則需要在resolve中配置enforceExtension : true,例如:

var path = require('path');module.exports = {
    entry : // ....,
    // ...
    resolve : {
        enforceExtension : true
    }};

此時,如果在js/app.js中引用js/text.js,就會報錯

// Errorimport './text';// Rightimport './text.js';

2.2 root/fallback/modulesDirectories 文件定位

webapck1 resolve中配置這三個屬性,是告訴webpack在引入模塊的時候必須要尋找的文件夾,webpack2中則直接更換成了一個單獨的屬性modules,默認(rèn)優(yōu)先搜索node_modules(注意,這是一個相對位置)

// configresolve: {
    // root : path.join(__dirname, "src")  webpack1方式
    modules : [        path.join(__dirname, "src"),    // 優(yōu)先于node_modules/搜索
        "node_modules"
    ]}// 修改 js/app.js// 在js文件夾中,增加一個lodash.js,如果按照上面的配置了modules,則會優(yōu)先加載我們自己的lodash庫import '../css/style.less';import _ from 'lodash';console.log(_.isObject([1, 2, 3]));document.getElementById('container').textContent = 'APP';// js/lodash.jsexport default {
    isObject(a) {
        console.log('this is my lodash library!');
        return a && typeof a === 'object';
    }}

得到的結(jié)果如下圖:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)

3. module相關(guān)

3.1 module.rules替換module.loaders

The old loader configuration was superseded by a more powerful rules system, which allows configuration of loaders and more. For compatibility reasons, the old module.loaders syntax is still valid and the old names are parsed. The new naming conventions are easier to understand and are a good reason to upgrade the configuration to using module.rules.

大意就是新的命名更容易理解(反正對于我來說就是換了個英文單詞:-D),同時還會兼容老的方式,也就是說,你照樣寫module.loaders還是可以的。

module : {
    // webpack1 way
    // loaders : [...]
    
    // now
    rules : [
        ...
    ]}

3.2 module[*].loader寫法

如果需要加載的模塊只需要一個loader,那么你還是可以直接用loader這個關(guān)鍵詞;如果要加載的模塊需要多個loader,那么你需要使用use這個關(guān)鍵詞,在每個loader中都可以配置參數(shù)。代碼如下:

module : {
    rules : [        { test : /\.js|\.jsx$/, loader : 'babel-loader' },
      
        /* 如果后面有參數(shù)需要傳遞到當(dāng)前的loader,則在后面繼續(xù)加上options關(guān)鍵詞,例如:          {             test : /\.js|\.jsx$/,             loader : 'babel-loader',             options : { presets : [ 'es2015', 'react' ] }           }        */
      
        {
            test : /\.css$/,
            // webpack1 way
            // loader : 'style!css'
          
            use : [ 'style-loader', 'css-loader' ]        },
        {
            test : /\.less$/,
            use : [                'style-loader',     // 默認(rèn)相當(dāng)于 { loader : 'style-loader' }
                {
                    loader : 'css-loader',
                    options : {
                        modules : true
                    }
                },
                'less-loader'
            ]        }
    ]}

3.2 取消自動添加-loader后綴

之前寫loader通常是這樣的:

loader : 'style!css!less'// equals toloader : 'style-loader!css-loader!less-loader'

都自動添加了-loader后綴,在webpack2中不再自動添加,如果需要保持和webpack1相同的方式,可以在配置中添加一個屬性,如下:

module.exports = {
    ...    resolveLoader : {
        moduleExtensions : ["-loader"]    }}// 然后就可以繼續(xù)這樣寫,但是官方并推薦這樣寫// 不推薦的原因主要就是為了照顧新手,直接寫會讓剛接觸的童鞋感到困惑// github.com/webpack/webpack/issues/2986use : [ 'style', 'css', 'less' ]

3.3 json-loader內(nèi)置啦

如果要加載json文件的童鞋再也不需要配置json-loader了,因為webpack2已經(jīng)內(nèi)置了。

4. plugins相關(guān)

4.1 UglifyJsPlugin 代碼壓縮插件

壓縮插件中的warningssourceMap不再默認(rèn)為true,如果要開啟,可以這樣配置

plugins : [    new UglifyJsPlugin({
        souceMap : true,
        warnings : true
    })
]

4.2 ExtractTextWebapckPlugin 文本提取插件

主要是寫法上的變動,要和webpack2配合使用的話,需要使用version 2版本

// webpack1 waymodules : {
    loaders : [        { 
            test : /\.css$/, 
            loader : ExtractTextPlugin.extract('style-loader', 'css-loader', { publicPath : '/dist' })        }   
    ]},plugins : [    new ExtractTextPlugin('bunlde.css', { allChunks : true, disable : false })
]// webapck2 waymodules : {
    rules : [        { 
            test : /\.css$/, 
            use : ExtractTextPlugin.extract({
                fallback : 'style-loader',
                use : 'css-loader',
                publicPath : '/dist'
            })        }
    ]},plugins : [    new ExtractTextPlugin({
        filename : 'bundle.css',
        disable : false,
        allChunks : true
    })
]

5. loaders的debug模式

在webpack1中要開啟loaders的調(diào)試模式,需要加載debug選項,在webpack2中不再使用,在webpack3或者之后會被刪除。如果你想繼續(xù)使用,那么請使用以下寫法:

// webpack1 waydebug : true// webapck2 way // webapck2將loader調(diào)試移到了一個插件中plugins : [    new webpack.LoaderOptionsPlugin({
        debug : true
    })
]

6. 按需加載方式更改

6.1 import()方式

在webpack1中,如果要按需加載一個模塊,可以使用require.ensure([], callback)方式,在webpack2中,ES2015 loader定義了一個import()方法來代替之前的寫法,這個方法會返回一個promise.

// 在js目錄中新增一個main.js// js/main.jsconsole.log('main.js');// webpack1 wayrequire.ensure([], function(require) {
    var _ = require('./lodash').default;
    console.log(_);
    console.log('require ensure');
    console.log(_.isObject(1));});// webpack2 way// 采用這種方式,需要promise 的 polyfill// 兩種方式:// 1. npm install es6-promise --save-dev//    require('es6-promise').polyfill();//// 2. babel方式,在webpack中配置babel插件//    npm install babel-syntax-dynamic-import --save-dev//    options : {//        presets : ['es2015'],//        plugins : ['syntax-dynamic-import']//    }import('./lodash').then(module => {
    let _ = module.default;
    console.log(_);
    console.log('require ensure');
    console.log(_.isObject(1));});

會得到的chunk文件,如下圖:

seo優(yōu)化培訓(xùn),網(wǎng)絡(luò)推廣培訓(xùn),網(wǎng)絡(luò)營銷培訓(xùn),SEM培訓(xùn),網(wǎng)絡(luò)優(yōu)化,在線營銷培訓(xùn)


http://www.cnblogs.com/rynxiao/p/7171583.html