webpack四個核心概念

webpack 是當下最熱門的前端資源模塊化和打包工具。它可以將許多鬆散的模塊(如 CommonJs 模塊、 AMD 模塊、 ES6 模塊、CSS、圖片、 JSON、Coffeescript、 LESS 等)按照依賴和規則打包成符合生產環境部署的前端資源。當 webpack 處理應用程序時,它會遞歸地構建一個依賴關係圖表,其中包含應用程序需要的每個模塊,然後將這些模塊打包成一個或多個 bundler,由瀏覽器加載

在瞭解 webpack 使用配置時,我們必須首先要熟悉下面四個核心概念:

entry:入口output:出口loaders:加載器plugins:插件

一、entry:入口

在 webpack 執行處理應用程序時,會形成一個依賴關係圖表。在這個圖表的起點就是入口起點(entry point),進入這個入口後,webpack 就可以計算出入口點依賴的模塊和庫。 如何在 webpack.config.js 中配置入口點呢?

單個入口語法

用法: entry: string |Array\

// webpack.config.js
const config = {
entry: './path/to/my/entry/file.js'
};
module.exports = config;

單個入口簡寫:

// webpack.config.js
const config = {
entry: {
main: './path/to/my/entry/file.js'
}
};

當你想要注入多個依賴文件時,可以向 entry 屬性傳入一個數組,數組是由文件路徑組成。這樣可以快速地設置 webpack 的配置,創建"多個主入口(multi-main entry)",但這種方法不利於配置的擴展。

對象語法

用法:entry: {[entryChunkName: string]: string|Array\}

// webpack.config.js
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
}

對象語法雖然繁瑣,但是它是應用程序入口最可擴展的方式。 **"可擴展的 webpack 配置"是指,可重用並且可以與其他配置組合使用。用於將關注點從環境、構建目標、運行時中分離。然後使用專門的工具(如 webpack-merge)將它們合併。

常用場景

1、分離應用程序和第三方庫入口

// webpack.config.js
const config = {
entry: {
app: './src/app.js',
vendors: './src/vendors.js'
}
};

webpack 創建的依賴圖是彼此完全分離、相互獨立的,上述寫法比較適用於單頁面應用程序。 執行 webpack 時,會使用 commonChunkPlugin 從 bundle 文件中提取 vendor 引用到 vendor bundle,並把引用 vendor 的部分替換為 webpack_require () 調用。 2、多頁面應用程序

// webpack.config.js
const config = {
entry: {
pageOne: './src/pageOne/index.js',
pageTwo: './src/pageTwo/index.js',
pageThree: './src/pageThree/index.js'
}
}

webpack 在多頁面應用中,會使用 commonChunkPlugin 為每個頁面應用創建 bundle 文件,在入口起點中時每個頁面都能對代碼和模塊實現複用。

二、output:輸出

這是屬性的作用是: 控制 webpack 如何向硬盤寫入編譯文件 。需要注意的是,即使是 存在多個入口起點,也只指定一個輸出配置1、用法 在 output 屬性中需要配置 filename 和 path 兩個配置項:

filename:輸出文件的文件名path:目標輸出的目錄,是一個 絕對路徑// webpack.config.js const config = { output: { filename: 'bundle.js', path: '/home/proj/public/assets' } };module.exports = config;

此配置將一個單獨的 bundle.js 文件輸出到 /home/proj/public/assets 目錄中。 2、多個入口起點 如果配置中存在多個入口起點,則需要使用一定的標識符確保每個輸出的文件名的唯一性。

// webpack.config.js
{
entry: {
app: './src/app.js',
search: './src/search.js'
},
output: {
filename: '[name].js',
path: __dirname + '/dist'
}
}
// 寫入到硬盤:./dist/app.js, ./dist/search.js

為了確保每個輸出 bundle 名稱的唯一性,需要借用一下方式來替換:

// 1、使用入口名稱
filename: "[name].bundle.js"
// 2、使用內部 chunk id
filename: "[id].bundle.js"
// 3、使用每次構建生成的唯一的 hash
filename: "[name].[hasn].bundle.js"
// 4、使用基於每個 chunk 內容的 hash
filename:"[chunkhash].bundle.js"

三、loader:加載器

loader 是用於 對模塊的源代碼進行轉換 。在需要加載模塊時對其做預處理,它可以將文件從不同的語言(如 typescript)轉換為 JavaScript,或將內聯圖像轉為 data URL,甚至允許你直接在 JavaScript 模塊中 import CSS文件。 1、使用 loader 的三種方式

配置(推薦):在 webpack.config.js 文件中指定 loader內聯: 在每個 import 語句中顯示指定 loaderCLI: 在 shell 命令中指定它們
配置: 在 modul.rules 中允許你在 webpack 配置中指定多個loader。module: { rules: [ { test: /.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } }] } ] }

內聯

import Styles from 'style-loader!css-loader?modules!./styles.css';

使用 ! 將資源中的 loader 分開,分開的每部分都相對於當前目錄解析。通過前置所有規則及使用 !,通過對選項傳遞查詢參數,可以對應覆蓋到配置中的任意 loader。 CLI

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

上述是使用 webpack 命令,對 .jade 文件使用 jade-loader,對 .css 文件使用 style-loader 和 css-loader。 2、loader 所具有的特性

loader 支持鏈式傳遞。能夠對資源使用流水線(pipeline)。一組鏈式的 loader 將按照 相反的順序執行 。loader 鏈中的第一個loader 返回值給下一個 loader。在最後一二 loader,返回 webpack 所預期的 JavaScript。loader 可以是 同步的,也可以是異步的 。運行在node.js 中,並且能夠執行任何可能的操作。接收查詢參數,用於對 loader 傳遞配置可以使用 options 對象進行配置除了使用package.json 常見的 main 屬性,還可以將普通的 你怕嗎 模塊導出為 loader插件可以為 loader 帶來更多特性loader 能夠產生而外的任意文件

四、plugins:插件

webpack 中的插件的出現,主要是為了實現 loader 無法實現的功能,是webpack 中核心部分。 webpack 插件是一個具有 apply 屬性的 JavaScript 對象,apply 屬性會被 webpack 編譯器調用,並且編譯器對象可以在整個編譯生命週期訪問。 用法 在 webpack 配置中,你可以攜帶參數或者選項,想 plugins 屬性中傳入 new 實例: 1、在配置中傳入 new 實例

// webpack.config.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: {
filename: 'my-first-webpack.bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
new HtmlWebpackPlugin({template: './src/index.html'})
]
};
module.exports = config;

原文:https://www.jianshu.com/p/b3c7cf338f41