如何一步一步配置webpack

大雄沒了哆啦A夢發表於2018-08-19

webpack一般包含四個配置,entry、output、module(loader)、plugins。

entry

入口檔案配置,可以配置單入口,也可以配置多入口, 。如果是單入口,則只需要配置一個字串,如果是多入口檔案則需要配置成{},值以 <name>: <entry file path> 的方式設定。

// 單入口檔案
entry: './src/index.js'
// 多入口檔案
entry: {
    'index': './src/index.js',
    'personal': './src/personal/index.js'
}
複製程式碼

這裡需要說下,建議使用多入口配置的方式時,不要一個一個手動配置,可以結合glob模組,用js去遍歷目錄下的js檔案(建議一般main.js),然後動態設定。可以看下我這邊檔案的思路:juejin.im/post/5b7392…

output

打包檔案配置,一般包含三個屬性publicPath、path、filename。

path: 打包的路徑,預設不指定的話是打包到根目錄的。一般我們會配置到根目錄下的某個資料夾,需要結合path模組一起使用,比如:

output: {
    path: path.resolve(__dirname, './dist')
}
複製程式碼

這樣就把打包檔案放入到根目錄的dist目錄下。

filename: 打包後的檔名,必須要配置,可以使用[name]來動態獲取入口檔案配置的。

entry: {
  'main': './src/index.js'  
},
output: {
    filename: '[name].js'
}
複製程式碼

則打包後的檔名為main.js。如果我們還要防止cdn/瀏覽器快取,我們可以設定hash值的檔名。

output: {
    filename: '[name].[chunkHash:8].js'  //會生成8位雜湊值的檔名
}
複製程式碼

publicPath:一般是cdn域名,如果是開發模式,可以配置成"/",表示根目錄。打包後的js引入的url的字首。如果配置publicPath為cdn.com,則引入的js的url應該是這樣的:

<script src="http://cdn.com/main.js"></script>
複製程式碼

通過設定entry和output就可以實現最簡單的打包了,但只是js檔案重新命名和移動位置而已。

loader

接下來我們希望使用js的es6語法,但是我們知道,現在瀏覽器對es6的支援還不全面,所以如果我們想要使用es6的話,就需要利用babel對我們的es6進行轉化,這個時候我們的loader就登場了。

webpack的設計理念,所有資源都是“模組”,webpack內部實現了一套資源載入機制,loader的功能,就是將符合我們配置條件的資源,進行載入並做一系列的轉化。使其變為瀏覽器可識別的資源。

所以,loader可以將瀏覽器無法識別的es6轉為瀏覽器識別的es5,將瀏覽器無法識別的less轉為瀏覽器識別的css,將瀏覽器無法識別的vue轉為瀏覽器識別的js....

為了使用es6語法,那麼我們接下來需要配置loaders,使用babel-loader來轉化es6語法。注意:要先安裝babel-loader(npm install --save-dev babel-loader babel-core)。

// webpack設計理論,所有資源都是模組,所以使用module
module: [
    // 配置規則
    rules: [
        {
            test: /\.js$/ , // 配置要轉為的資源規則,正規表示式,即所有的js檔案
            exclude: /node_modules/, // 排除的檔案
            loader: 'babel-laoder', // 使用babel loader來轉化es6
            options: {
                presets: ['es2015']
            } // 將es6轉為es5 
        }
    ]
    // 這裡多說一句,options配置。options配置是給loader傳的引數,有興趣的同學可以去看下如何實現自定義的loader,如果你需要在你自定義的loader裡面傳參,就要用到這個配置。  
]
複製程式碼

這樣我們就完成了babel-loader的配置了,然後就可以使用es6語法了對不對,哈哈這樣你就錯了,還差一步,還需要在根目錄下新增.babelrc,如果沒有這個檔案,則會報錯。這個檔案的內容和options裡面的完全一樣就可以(其實也可以為空)。

為什麼一定要.babelrc檔案,因為babel工具和模組的使用,都必須先寫好.babelrc。有興趣的同學可以看下阮一峰關於的babal文章:www.ruanyifeng.com/blog/2016/0…

好了,那麼我們通過loader實現了對es6的支援了,loader的作用就是這樣。
如果我們還想使用vue,則我們還需要新增vue-loader,使用vue,還需要配置VueLoaderPlugin的plugin,不然webpack不認識自定標籤。

所以我們知道了,為啥我們可以使用.vue這個瀏覽器無法識別的檔案格式呢,因為我們有vue-loader幫我們把它轉為js了☺。

plugins

接下來,我們希望webpack幫我們把js進行壓縮,節省我們http請求的網路頻寬,所以我們的plugins登場了。
plugins的作用就是實現laoder無法實現的其他事,它是用來擴充套件webpack功能的,會在整個構建過程中生效,執行相關的任務,比如UglifyJsPlugin外掛就是在構建的過程中將js程式碼進行壓縮,CommonsChunkPlugin可以將整個打包過程中通用的js程式碼給提取出來。

plugins是個陣列,配置UglifyJsPlugin如下

devtool: "#source-map",
plugins: [
    new webpack.optimize.UglifyJsPlugin({
        sourceMap: true
    }),
    .... // 其他plugin
]
複製程式碼

一般我們壓縮後的檔案希望能夠還原,這個時候就要配置sourceMap為true,同時配置devtool的值為"#source-map",這樣就會生成SourceMap檔案了。

本地開發伺服器

開發的時候,我們希望我們的程式碼在本地執行,web pack提供了一個webpack-dev-server。配置如下:

 devServer: {
    port: 80,  //webpack-dev-server伺服器啟動的埠
    host: '0.0.0.0', //webpack-dev-server伺服器啟動的host
    contentBase: path.join(__dirname, 'src')  //監聽src目錄下的檔案變化,然後熱啟動
  }
複製程式碼

然後我們可以通過命令啟動,注意--hot指定是熱啟動,監聽contentBase目錄下的檔案變化,--config指定配置目錄。

webpack-dev-server --hot --config build/webpack.conf.js
複製程式碼

啟動webpack-dev-server的時候傳參可以兩種方式:
1、直接在命令列中以<--引數>的方式,像上面的hot和config
2、在webpack.config.js在的devServer配置,像上面的port等。

我們還可以修改package.json,通過npm來啟動指令碼,簡化啟動命令。

"scripts": {
    "start": "webpack-dev-server --hot --config build/webpack.conf.js",
    "dev": "npm run start",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
},
複製程式碼

這樣就可以通過npm run start的方式啟動webpack-dev-server了。

遇到問題: ==You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.==
原因:因為預設情況下,import vue from 'vue'的vue是vue.common.js,而不是vue.js,而vue.common.js是不支援template語法的,所以通過別名可以解決這個問題,讓import的時候去import vue.js而不是vue.common.js。
webpack當中配置別名如下:

resolve:{
    alias:{
        'vue':'vue/dist/vue.js'
    }
},
複製程式碼

通用配置

我們使用webpack的時候,希望對圖片/js/css等都進行優化打包,所以需要有支援圖片/css/js優化的一些loader和plugins配置。下面講一些比較通用的配置:

為了將圖片轉為base64(減少http請求)和解決圖片引用路徑問題,我們需要url-loader(整合了file-loader)。
為了在js中引入css,我們需要css-loader。如果你還想將css插入到頁面的<style>裡面,你還需要style-loader。 如果css-loader和style-loader一起用,這裡需要注意了,由於webpack loader的執行順序是從右到左,所以你要先設定style-loader在設定css-loader,因為webpack是先將所有css模組依賴解析完得到計算結果再建立style標籤的。

為了將所有公共的程式碼提取出來,減少打包後的js檔案大小,使用 CommonsChunkPlugin 為每個頁面間的應用程式共享程式碼建立 bundle。由於入口起點增多,多頁應用能夠複用入口起點之間的大量程式碼/模組,從而可以極大地從這些技術中受益。隨帶一提,webpack4有個SplitChunksPlugin效能比CommonsChunckPlugin好。

為了強制把css從js檔案中獨立出來中,而不想讓其放在js中,要用到ExtractTextPlugin(style-loader會將所有的css都打包如js中,js在執行時再放入html的style當中)。

demo: github.com/VikiLee/web…

相關文章