# 入口(Entry)
webpack 將創建所有應用程序的**依賴關系圖表(dependency graph)**。圖表的起點被稱之為**入口起點(entry point)**。入口起點告訴 webpack 從哪里開始,并遵循著依賴關系圖表知道要打包什么。可以將您應用程序的入口起點認為是根上下文(contextual root)或 app 第一個啟動文件。
在 webpack 中,我們使用 webpack 配置對象(webpack configuration object) 中的` entry` 屬性來定義入口。
一個最簡單的例子:
webpack.config.js
~~~javascript
module.exports = {
entry: './path/to/my/entry/file.js'
};
~~~
這里有多種方式聲明應用程序所需的特定 entry 屬性。
## 單個入口(簡寫)語法
用法:`entry: string|Array<string>`
webpack.config.js
~~~javascript
const config = {
entry: './path/to/my/entry/file.js'
};
module.exports = config;
~~~
entry 屬性的單個入口語法,是下面的簡寫:
~~~javascript
const config = {
entry: {
main: './path/to/my/entry/file.js'
}
};
~~~
> 向 entry 屬性傳入「文件路徑(file path)數組」將創建“多個主入口(multi-main entry)”。在你想要多個依賴文件一起注入,并且將它們的依賴導向(graph)到一個“chunk”時,這種傳入數組的方式比較有效。
當你正在尋找為「一個應用程序或只有一個入口起點的工具(即 library)」快速設置一個 webpack 配置的時候,這會是個很不錯的選擇。但是,使用此語法擴展(extend or scale)配置沒有太多的靈活性。
## 對象語法
用法:entry: {[entryChunkName: string]: string|Array<string>}
webpack.config.js
~~~javascript
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};
~~~
對象語法會比較繁瑣。然而,這是應用程序中定義入口的最可擴展的方式。
> “可擴展的 webpack 配置”是指,可重用并且可以與其他配置組合使用。這是一種流行的技術,用于將關注點(concern)從環境(environment)、構建目標(build target)、運行時(runtime)中分離。然后使用專門的工具(如 webpack-merge)將它們合并。
## 常見場景
以下列出入口配置和它們的實際用例:
### 分離 應用程序(app) 和 公共庫(vendor) 入口
webpack.config.js
~~~javascript
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};
~~~
**1. 原理**
從表面上看,這告訴我們 webpack 從 app.js 和 vendors.js 開始創建依賴圖表(dependency graph)。這些圖表是彼此完全分離、互相獨立的(每個 bundle 中都有一個 webpack 引導(bootstrap))。這種方式比較常見于只有一個入口起點(不包括 vendor)的單頁應用程序(single page application)中。
**2. 原因**
這樣設置允許你使用 `CommonsChunkPlugin` 從「應用程序 bundle」中提取 vendor 引用(vendor reference) 到 vendor bundle,并把 vendor 引用的部分替換為` __webpack_require__() `調用。如果應用程序 bundle 中沒有 vendor 代碼,那么你可以在 webpack 中實現被稱為**長效緩存**的通用模式。
### 多個頁面應用程序
webpack.config.js
~~~javascript
const config = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
};
~~~
我們告訴 webpack 需要 3 個獨立分離的依賴圖表(如上面的示例)。
在多頁應用中,服務器將為你獲取一個新的 HTML 文檔。頁面重新加載新文檔,并且資源被重新下載。然而,這給了我們特殊的機會去做很多事:
* 使用 `CommonsChunkPlugin` 為每個頁面間的應用程序共享代碼創建 bundle。由于入口起點增多,多頁應用能夠在入口起點重用大量代碼/模塊,這樣可以極大的從這些這些技術受益。
# 輸出(Output)
此選項影響 compilation 對象的輸出。output 選項控制 webpack 如何向硬盤寫入編譯文件。注意,即使可以存在多個入口起點,但只指定一個輸出配置。
## 用法
在 webpack 中配置 output 屬性的最低要求是,將它的值設置為一個對象,包括以下兩點:
* 編譯文件的文件名(filename),首選推薦:// main.js || bundle.js || index.js
* output.path 對應一個絕對路徑,此路徑是你希望一次性打包的目錄。
webpack.config.js
~~~javascript
const config = {
output: {
filename: 'bundle.js',
path: '/home/proj/public/assets'
}
};
module.exports = config;
~~~
## 選項
output屬性還有很多可選傳入的值,具體可以訪問[輸出選項](https://doc.webpack-china.org/concepts/output/)
## 多個入口起點
如果配置創建了多個單獨的 "chunk"(例如,使用多個入口起點或使用像 CommonsChunkPlugin 這樣的插件),則應該 **使用占位符(substitutions)** 來確保每個文件具有唯一的名稱。
~~~
{
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
// 寫入到硬盤:./dist/app.js, ./dist/search.js
~~~
使用入口名稱:
~~~
filename: "[name].bundle.js"
~~~
使用內部 chunk id
~~~
filename: "[id].bundle.js"
~~~
使用每次構建過程中,唯一的 hash 生成
~~~
filename: "[name].[hash].bundle.js"
~~~
使用基于每個 chunk 內容的 hash:
~~~
filename: "[chunkhash].bundle.js"
~~~
注意此選項被稱為文件名,但是你還是可以使用像 "js/[name]/bundle.js" 這樣的文件夾結構。
注意,此選項不會影響那些「按需加載 chunk」的輸出文件。對于這些文件,請使用 output.chunkFilename 選項來控制輸出。同樣也不影響通過 loader 創建的文件,對于這些文件,請查看 loader 選項來輸出控制。
可以使用以下替換模板字符串(通過 webpack 內部的[TemplatedPathPlugin]TemplatedPathPlugin):
| 占位符 | 描述|
|---|---|
| [hash]| 模塊標識符(module identifier)的 hash|
| [chunkhash]| chunk 內容的 hash|
| [name]| 模塊名稱|
| [id]| 模塊標識符(module identifier)|
| [file]| 模塊文件名稱|
| [filebase]| 模塊 basename|
| [query]| 模塊的 query,例如,文件名 ? 后面的字符串|
`[hash] `和 `[chunkhash] `的長度可以使用 `[hash:16]`(默認為20)來指定。或者,通過指定`output.hashDigestLength` 在全局配置長度。