# 概念
webpack 是高度可配置的,有四個核心概念:
* 入口(entry)
* 輸出(output)
* loader
* 插件(plugins)
## 入口(entry)
**入口起點(entry point)** 指示 webpack 應該使用哪個模塊,來作為構建其內部*依賴圖*的開始。進入入口起點后,webpack 會找出有哪些模塊和庫是入口起點(直接和間接)依賴的。
每個依賴項隨即被處理,最后輸出到稱之為 *bundles* 的文件中。
可以通過在 [webpack 配置](https://doc.webpack-china.org/configuration)中配置 `entry` 屬性,來指定一個入口起點(或多個入口起點)。
接下來我們看一個 `entry` 配置的最簡單例子:
**webpack.config.js**
```js
module.exports = {
entry: './path/to/my/entry/file.js'
};
```
> 根據應用程序的特定需求,可以以多種方式配置 `entry` 屬性。
## 出口(output)
**output** 屬性告訴 webpack 在哪里輸出它所創建的 *bundles*,以及如何命名這些文件。你可以通過在配置中指定一個 `output` 字段,來配置這些處理過程:
**webpack.config.js**
```js
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'
}
};
```
在上面的例子中,我們通過 `output.filename` 和 `output.path` 屬性,來告訴 webpack bundle 的名稱,以及我們想要生成(emit)到哪里。
> 你可能會發現術語**生成(emitted 或 emit)** 貫穿了我們整個文檔和[插件 API](https://doc.webpack-china.org/api/plugins)。它是“生產(produced)”或“釋放(discharged)”的特殊術語。
> `output` 屬性還有[更多可配置的特性](https://doc.webpack-china.org/configuration/output),如果你想要了解更多關于 `output` 屬性的概念,你可以通過[閱讀概念章節](https://doc.webpack-china.org/concepts/output)來了解更多。
## loader
*loader* 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉換為 webpack 能夠處理的有效[模塊](https://doc.webpack-china.org/concepts/modules),然后你就可以利用 webpack 的打包能力,對它們進行處理。
本質上,webpack loader 將所有類型的文件,轉換為應用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。
> 注意,loader 能夠 `import` 導入任何類型的模塊(例如 `.css` 文件),這是 webpack 特有的功能,其他打包程序或任務執行器的可能并不支持。我們認為這種語言擴展是有很必要的,因為這可以使開發人員創建出更準確的依賴關系圖。
在更高層面,在 webpack 的配置中 **loader** 有兩個目標:
1. `test` 屬性,用于標識出應該被對應的 loader 進行轉換的某個或某些文件。
2. `use` 屬性,表示進行轉換時,應該使用哪個 loader。
**webpack.config.js**
```js
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
}
};
module.exports = config;
```
以上配置中,對一個單獨的 module 對象定義了 `rules` 屬性,里面包含兩個必須屬性:`test` 和 `use`。這告訴 webpack 編譯器(compiler) 如下信息:
> “嘿,webpack 編譯器,當你碰到「在 `require()`/`import` 語句中被解析為 '.txt' 的路徑」時,在你對它打包之前,先**使用** `raw-loader` 轉換一下。”
> 重要的是要記得,**在 webpack 配置中定義 loader 時,要定義在 module.rules 中,而不是 rules**。然而,在定義錯誤時 webpack 會給出嚴重的警告。為了使你受益于此,如果沒有按照正確方式去做,webpack 會“給出嚴重的警告”
loader 還有更多的[具體配置屬性](https://doc.webpack-china.org/concepts/loaders)。
## 插件(plugins)
loader 被用于轉換某些類型的模塊,而插件則可以用于執行范圍更廣的任務。插件的范圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。[插件接口](https://doc.webpack-china.org/api/plugins)功能極其強大,可以用來處理各種各樣的任務。
想要使用一個插件,你只需要 `require()` 它,然后把它添加到 `plugins` 數組中。多數插件可以通過選項(option)自定義。你也可以在一個配置文件中因為不同目的而多次使用同一個插件,這時需要通過使用 `new` 操作符來創建它的一個實例。
**webpack.config.js**
```js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝
const webpack = require('webpack'); // 用于訪問內置插件
const path = require('path');
const config = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js'
},
module: {
rules: [
{ test: /\.txt$/, use: 'raw-loader' }
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;
```
webpack 提供許多開箱可用的插件!查閱[插件列表](https://doc.webpack-china.org/plugins)獲取更多信息。