webpack工作内容可以用官網的一個圖來表示
從圖中可以看出,webpack是現在js應用程式的靜态打包器,當webpack處理一個程式時,會逐漸找到各個子產品的依賴關系形成依賴關系圖,然後把這些子產品打包成一個或者多個檔案。
1,入口檔案entry
webpack處理各個子產品關系時,需要有一個入口作為開端,來形成依賴關系圖,entry就是用來指定這個入口檔案的。
a、如果隻是單頁面應用時,入口檔案隻需要指定一個入口檔案。預設值為 ./src
./src
接下來我們看一個
entry
配置的最簡單例子:
module.exports = {
entry: './path/to/my/entry/file.js'
};
b、如果是多頁面應用,入口檔案将會有多個。
module.exports = {
entry:{
page1: './src/page1.js',
page2: './src/page2.js'
}
};
page1、page2這種key将會在output中用到,也可以不用。
2,輸出檔案output
output将會告訴webpack打包好的檔案存放在哪裡,檔案名是什麼。
a、單頁面示例
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
}
};
上邊示例中path表示輸出的檔案的路徑,預設值路徑是./dist,基本上打包好的檔案都将會輸出到這個檔案夾裡。其中path.resolve是擷取檔案的相對路徑。也可以直接寫成“./dist”
filename是打包後生成的js的名稱。如果這個名稱想用entry裡的名字或者是多頁面應用的話,可以用多頁面示例的方法來寫
b、多頁面示例(通過占位符來確定檔案名稱唯一)
const path = require('path');
module.exports = {
entry:
{
page1: path.resolve(__dirname,'../src/index.js'),
page2: path.resolve(__dirname,'../src/page2.js'),
},
output:{
path: path.resolve(__dirname,"../dist"),
filename: '[name].js',
}
}
上邊例子中output裡filename的形式發生了變化,[name]通過占位符來確定檔案名稱唯一,
【name】取值為entry對象裡key的值,運作以上示例後可以在dist目錄看到檔案為page1.js和page2.js.
注:output這塊還有輸出成元件的配置參數等,後續文章裡會單獨介紹。
3,loaders
webpack預設隻支援打包js檔案。當我們程式裡用到vue、less、react等非js檔案時,需要用loader将對應的檔案轉為webpack可以處理的形式。和webpack處理js一樣,形成程式依賴圖,最後會把這些非js檔案一起打包到最終輸出的js裡。
在更高層面,在 webpack 的配置中 loader 有兩個目标:
-
屬性,用于辨別出應該被對應的 loader 進行轉換的某個或某些檔案。test
-
屬性,表示進行轉換時,應該使用哪個 loader。use
module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', } ] }
lodaer應該放在module下,rules裡可以配置多個loaders,其中test為正規表達式比對到檔案,入上訴代碼裡
test: /.vue$/表示已.vue結尾的檔案,loader表示要用的轉換器。
注:上訴代碼為編譯vue用到的,但是隻有loader是不能正确轉義vue的,需要結合plugins的插件。是以完整代碼在最後。
4,plugins
loader 被用于轉換某些類型的子產品,而插件比loader範圍更廣一些。插件的範圍包括,從打包優化和壓縮,一直到重新定義環境中的變量,都會參與。
想要使用一個插件,可以通過
它,然後把它添加到require()
plugins
數組中。多數插件可以通過選項(option)自定義。
也可以使用
操作符來建立它的一個執行個體,這樣可以多次使用同一個插件(比如HtmlWebpackPlugin在多頁面時多次使用)。new
'use strict' const path = require('path'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const webpack = require('webpack'); module.exports = { entry:{ index: path.resolve(__dirname,'../src/index.js'), page2: path.resolve(__dirname,'../src/page2.js'), }, output:{ path: path.resolve(__dirname,"../dist"), filename: '[name].js', }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', } ] }, plugins:[ new VueLoaderPlugin(), new webpack.LoaderOptionsPlugin({ vue: { compilerOptions: { preserveWhitespace: false } } })] }
上訴例子中,plugins包含了兩個插件,VueLoaderPlugin和LoaderOptionsPlugin,這兩個需要先安裝在使用。
webpack裡有很多插件,可以實作各種各樣的功能,這些具體的之後會說的。
5,contextPath
基礎目錄,絕對路徑,用于entry的上下文,是入口檔案所處目錄的絕對路徑。
const path = require('path');
module.exports = {
context: path.resolve(__dirname, '../src'),
entry:{
index: './index.js',
//如果未設定context,需要以下面方式設定入口檔案路徑
page2: path.resolve(__dirname,'../src/page2.js'),
},
};
(index.js相對于目前的檔案的目錄為…/src/index.js)
上訴代碼中,如果設定了context,entry的值就可以直接配置為“./index.js”。打包時會直接從context所指向的目錄去查找對應的檔案。
預設值為目前路徑
6,完整示例
代碼目錄如下:
在index.html裡直接引入dist裡的index.js檔案,可以通路index.html,可以看到在vue裡寫的文字。
注(如果vue裡有圖檔或者樣式不會被識别,因為沒有加對應的loader)
代碼示例https://github.com/ccDbb/webpack-test中history的v1版本中。
可能遇到的錯誤資訊
1,ERROR in ./src/view/index.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
[vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.
@ ./src/index.js 2:0-36 6:21-26
vue-template-compiler沒有按照或者版本和vue不比對