您好,登錄后才能下訂單哦!
這篇“Webpack4.x的四個核心概念是什么”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Webpack4.x的四個核心概念是什么”文章吧。
需要理解四個核心概念:
入口(entry)
輸出(output)
loader
插件(plugins)
指定 webpack 由哪個模塊作為項目構建的開始。
通過配置 entry
屬性,指定一個或多個起點,默認值 ./src
:
module.exports = { entry: './path/leo/file.js' };
用法:entry: string|Array
當 entry
中沒有配置入口的文件對象的名稱,默認使用的是 main
名稱,輸出就是 main.js
,即:
// 默認情況 module.exports = { entry: './path/leo/file.js' }; // 配置單個入口 const config = { entry: { main: './path/leo/file.js' } };
可以看出,實際上 默認情況 只是 配置單個入口 的簡寫形式。
另外,文件路徑我們也可以傳入一個數組,就會將多個依賴文件一起注入:
const config = { entry: { main: ['./path/leo/file.js', './path/leo/index.js', './path/leo/server.js'] } };
用法:entry: {[entryChunkName: string]: string|Array}
多個文件完全分離,互相獨立(每個 bundle 中都有一個 webpack 引導(bootstrap)),常見于只有一個入口的單頁面應用。
const config = { entry: { app: './src/app.js', vendors: './src/vendors.js' } };
指定 webpack 最終輸出的文件輸出位置和文件名等信息。
通過配置 output
屬性,指定輸出位置和文件名,默認輸出位置為 ./dist
:
兩個屬性:
path
:輸出的目錄絕對路徑;
filename
:輸出的文件名稱;
const path = require('path'); module.exports = { entry: './path/leo/file.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'leo-webpack.bundle.js' } };
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }
更多占位符,點擊查看
output: { path: "/home/proj/cdn/assets/[hash]", publicPath: "http://cdn.example.com/assets/[hash]/" }
關于output.publicPath , 點擊查看
如果編譯時不知道最終文件的 publicPath ,可以留空,并在入口文件中動態設置。或者在入口起點設置 __webpack_public_path__ 來忽略它。
__webpack_public_path__ = myRuntimePublicPath
讓 webpack 能夠處理非 JS 文件,在 import
或 “加載”模塊時預處理文件。
通過配置 loader 兩個屬性來實現:
test
屬性,用來標識出應該被對應的 loader 進行轉換的某個或多個文件;
use
屬性,表示轉換時要用哪個 loader;
const path = require('path'); const config = { output: { filename: 'leo-webpack.bundle.js' }, module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] } }; module.exports = config;
如安裝一個 css-loader
和 ts-loader
使得 webpack 可以加載 CSS 文件,或者將 TypeScript
轉換成 JavaScript
:
npm install --save-dev css-loader ts-loader
使用:
// webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: 'css-loader' }, { test: /\.ts$/, use: 'ts-loader' } ] } };
配置(推薦):在 webpack.config.js 文件中指定 loader。
指定多個loader:
module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }
內聯:在每個 import 語句中顯式指定 loader。
可以在 import
語句或任何等效于 import
的方式中指定 loader,使用 !
將多個 loader 分開,每個部分都是相對于當前目錄的解析。
import Styles from 'style-loader!css-loader?modules!./styles.css';
盡可能使用 module.rules,減少代碼量,并且在出錯時,更快地調試和定位 loader 中的問題。
CLI:在 shell 命令中指定它們。
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
loader 會從數組最后一個開始,往前一個一個加載:
// webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] } };
loader 支持鏈式傳遞。
能夠對資源使用流水線(pipeline)。一組鏈式的 loader 將按照相反的順序執行。loader 鏈中的第一個 loader 返回值給下一個 loader。在最后一個 loader,返回 webpack 所預期的 JavaScript。
loader 可以是同步的,也可以是異步的。
loader 運行在 Node.js 中,并且能夠執行任何可能的操作。
loader 接收查詢參數。用于對 loader 傳遞配置。
loader 也能夠使用 options 對象進行配置。
除了使用 package.json 常見的 main 屬性,還可以將普通的 npm 模塊導出為 loader,做法是在 package.json 里定義一個 loader 字段。
插件(plugin)可以為 loader 帶來更多特性。
loader 能夠產生額外的任意文件。
另外可以查看 如何編寫 loader?
讓 webpack 能夠執行更多任務,從優化和壓縮,到重新定義環境中的變量,非常強大。
插件目的在于解決 loader 無法實現的其他事。
使用時,只需要 require
它,并添加到 plugins
數組,通過 new
實例化即可:
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通過 npm 安裝 const webpack = require('webpack'); // 用于訪問內置插件 const config = { module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] }, plugins: [ new HtmlWebpackPlugin({template: './src/index.html'}) ]}; module.exports = config;
原理剖析:
webpack 插件是一個具有 apply
屬性的 JavaScript 對象。apply
屬性會被 webpack compiler
調用,并且 compiler
對象可在整個編譯生命周期訪問。
用法:
由于插件可以攜帶參數/選項,你必須在 webpack
配置中,向 plugins
屬性傳入 new
實例。
配置:
// webpack.config.js const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝 const webpack = require('webpack'); //訪問內置的插件 const path = require('path'); const config = { entry: './path/leo/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;
通過配置 mode
參數,指定當前的開發模式,有 development
和 production
兩個值:
module.exports = { mode: 'production' };
也可以通過 CLI 參數傳遞:
webpack --mode=production
參數描述:
選項 | 描述 |
---|---|
development | 會將 process.env.NODE_ENV 的值設為development 。啟用 NamedChunksPlugin 和 NamedModulesPlugin 。 |
production | 會將 process.env.NODE_ENV 的值設為 production 。啟用 FlagDependencyUsagePlugin , FlagIncludedChunksPlugin , ModuleConcatenationPlugin , NoEmitOnErrorsPlugin ,OccurrenceOrderPlugin , SideEffectsFlagPlugin 和 UglifyJsPlugin 。 |
記住,只設置 NODE_ENV,則不會自動設置 mode。
webpack 的配置文件,是導出一個對象的 JavaScript 文件,由 webpack 根據對象定義的屬性進行解析。
因為 webpack 配置是標準的 Node.js CommonJS 模塊,你可以做到以下事情:
通過 require(...)
導入其他文件;
通過 require(...)
使用 npm
的工具函數;
使用 JavaScript 控制流表達式,例如 ?:
操作符;
對常用值使用常量或變量;
編寫并執行函數來生成部分配置;
但應避免以下做法:
在使用 webpack 命令行接口(CLI)(應該編寫自己的命令行接口(CLI),或使用 --env
)時,訪問命令行接口(CLI)參數;
導出不確定的值(調用 webpack 兩次應該產生同樣的輸出文件);
編寫很長的配置(應該將配置拆分為多個文件);
// webpack.config.js var path = require('path'); module.exports = { mode: 'development', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } };
除了到處單個配置對象,我們也可以有一些其他方式:
我們可能需要同時考慮到開發環境和生產環境,在 webpack.config.js
中實現,我們會有至少兩種方式:
導出一個配置對象來代替;
導出一個可以傳入參數的函數:
傳入兩個參數:環境變量(查看 CLI 文檔的環境選項)和 map 對象(argv
)參數。
module.exports = function(env, argv) { return { mode: env.production ? 'production' : 'development', devtool: env.production ? 'source-maps' : 'eval', plugins: [ new webpack.optimize.UglifyJsPlugin({ compress: argv['optimize-minimize'] // 只有傳入 -p 或 --optimize-minimize }) ] }; };
webpack 將運行由配置文件導出的函數,并且等待 Promise
返回。便于需要異步地加載所需的配置變量。
module.exports = () => { return new Promise((resolve, reject) => { setTimeout(() => { resolve({ entry: './app.js', /* ... */ }) }, 5000) }) }
我們把導出對象設置成一個數組,webpack 運行時,會將所有配置對象都構建,這對于針對多個構建目標(例如 AMD 和 CommonJS)打包一個 library非常有用。
module.exports = [{ output: { filename: './dist-amd.js', libraryTarget: 'amd' }, entry: './app.js', mode: 'production', }, { output: { filename: './dist-commonjs.js', libraryTarget: 'commonjs' }, entry: './app.js', mode: 'production', }]
webpack 接受以多種編程和數據語言編寫的配置文件。支持的文件擴展名列表,可以在 node-interpret 包中找到。使用 node-interpret,webpack 可以處理許多不同類型的配置文件。
文檔介紹:《使用不同語言進行配置(configuration languages)》
為了用 TypeScript 書寫 webpack 的配置文件,必須先安裝相關依賴:
npm install --save-dev typescript ts-node @types/node @types/webpack
使用 TypeScript 書寫 webpack 的配置文件:
// webpack.config.ts import path from 'path'; import webpack from 'webpack'; const config: webpack.Configuration = { mode: 'production', entry: './foo.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'foo.bundle.js' } }; export default config;
在以下的例子中,使用了 JSX
(React
形式的 javascript)以及 Babel
來創建 JSON
形式的 webpack 配置文件:
首先安裝依賴:
npm install --save-dev babel-register jsxobj babel-preset-es2015
設置配置:
// .babelrc { "presets": [ "es2015" ] } // webpack.config.babel.js import jsxobj from 'jsxobj'; // example of an imported plugin const CustomPlugin = config => ({ ...config, name: 'custom-plugin' }); export default ( );
開發中將程序分解成離散功能塊,成為模塊。
而 webpack 模塊能夠以各種形式表達他們的依賴關系:
es6: import
語句;
CommonJS: require()
語句;
AMD: define
和 require
語句;
css/sass/less
文件中的 @import
語句;
樣式(url(...)
)或 HTML 文件中的圖片鏈接(image url
);
查看更多 模塊方法。
使用 resolver
庫來找到模塊的絕對路徑,幫助 webpack 找到 bundle 中需要引入的模塊代碼,這些代碼包含在每個 require
/ import
語句中,在模塊打包中,webpack 使用 enhanced-resolve 來解析文件路徑
webpack 解析規則: 使用 enhanced-resolve
,webpack
支持解析三種文件路徑:
絕對路徑:
import "/home/me/file"; import "C:\\Users\\me\\file";
相對路徑:
import "../src/file1"; import "./file2";
模塊路徑:
import "module"; import "module/lib/file";
模塊將在 resolve.modules
中指定的所有目錄中搜索,另外可以使用 resolve.alias
做初始化模塊路徑。
解析器(resolver)檢查路徑是否指向文件或目錄,如果是指向文件:
如果有文件拓展名則直接打包;
否則使用 [resolve.extensions
] 選項作為文件擴展名來解析,配置解析器在解析中能夠接受哪些擴展名(例如 .js
, .jsx
)。
如果是指向文件夾,則按照步驟找到正確拓展名的文件:
如果文件夾中包含 package.json
文件,則按照順序查找 resolve.mainFields 配置選項中指定的字段。并且 package.json
中的第一個這樣的字段確定文件路徑。
如果不存在 package.json
文件或者 package.json
文件中的 main
字段沒有返回一個有效路徑,則按照順序查找 resolve.mainFiles
配置選項中指定的文件名,看是否能在 import/require
目錄下匹配到一個存在的文件名。
文件擴展名通過 resolve.extensions
選項采用類似的方法進行解析。
Loader 解析遵循與文件解析器指定的規則相同的規則。但是 resolveLoader
配置選項可以用來為 Loader 提供獨立的解析規則。
每個文件系統訪問都被緩存,以便更快觸發對同一文件的多個并行或串行請求。在觀察模式下,只有修改過的文件會從緩存中摘出。如果關閉觀察模式,在每次編譯前清理緩存。
有關上述配置的更多信息,請查看解析 API學習。
注意:webpack 的 target
屬性不要和output.libraryTarget
屬性混淆。
在你的 webpack 配置中設置 target
的值:
module.exports = { target: 'node' };
在上面例子中,使用 node
webpack 會編譯為用于「類 Node.js」環境(使用 Node.js 的 require
,而不是使用任意內置模塊(如 fs
或 path
)來加載 chunk)。
更多詳細的值,可以參考 構建目標(targets)
盡管 webpack 不支持向 target
傳入多個字符串,你可以通過打包兩份分離的配置來創建同構的庫:
var path = require('path'); var serverConfig = { target: 'node', output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.node.js' } //… }; var clientConfig = { target: 'web', // <=== 默認是 'web',可省略 output: { path: path.resolve(__dirname, 'dist'), filename: 'lib.js' } //… }; module.exports = [ serverConfig, clientConfig ];
以上就是關于“Webpack4.x的四個核心概念是什么”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。