好記性不如爛筆頭-Webpack篇
一、Entry
定義:指示webpack應(yīng)該使用哪個(gè)模塊,來作為構(gòu)建其內(nèi)部依賴圖的開始。(從入口開始,搜尋并遞歸解析出所有入口依賴的模塊)
1.1 單入口
對于單入口文件,其值為string類型,打包形成一個(gè)chunk,輸出一個(gè)bundle文件。
- module.exports = {
- entry: './src/index.js'
- }
1.2 多入口
輸入為一個(gè)數(shù)組,但是入口文件最終只會形成一個(gè)chunk,輸出出去只有一個(gè)bundle文件。
- module.exports = {
- entry: ['./src/index.js','./src/add.js']
- }
輸入為對象,有幾個(gè)入口文件就形成幾個(gè)chunk,輸出幾個(gè)bundle1文件
- module.exports = {
- entry: {
- index: './src/index.js',
- add: './src/add.js',
- }
- }
1.3 動(dòng)態(tài)入口
輸入為一個(gè)函數(shù)(同步或異步),用于動(dòng)態(tài)的返回上面所需的入口內(nèi)容。
- module.exports = {
- entry: () => new Promise((resolve) => resolve(['./src/index.js','./src/add.js']))
- }
二、Output
指示webpack如何去輸出、以及在哪里輸出你的bundle、asset 和其他你所打包或使用 webpack載入的任何內(nèi)容。
2.1 名稱
對于輸出的名字,常用的主要有兩類:filename(輸出bundle名稱)和chunkFilename(非入口chunk名稱)。
filename(配置輸出文件的名稱,為string類型)
- module.exports = {
- //文件名稱(指定名稱+目錄)
- filename: '[name].js'
- }
chunkFilename(配置非入口chunk的名稱)
對于非入口文件,產(chǎn)生方式有兩種:方式一是通過import語法會將一個(gè)文件單獨(dú)分割成一個(gè)chunk;方式二是利用optimization將node_modules分割成chunk。(見后續(xù)博客)
- module.exports = {
- //非入口chunk名稱
- chunkFilename: '[name]_chunk.js'
- }
2.2 路徑
對于配置的輸出路徑,常用的主要有兩個(gè):path和publicPath。
path(配置輸出文件存放的目錄,必須是string類型的絕對路徑
- module.exports = {
- path: path.resolve(__dirname, 'dist_[hash]')
- }
publicPath(所有資源引入公共路徑前綴)
- module.exports = {
- publicPath: 'https://cdn.example.com/'
- }
2.3 輸出庫
當(dāng)用webpack去構(gòu)建一個(gè)可以被其它模塊導(dǎo)入使用的庫時(shí),需要用到libraryTarget和library。其中l(wèi)ibraryTarget配置何種方式導(dǎo)出庫;library配置導(dǎo)出庫名稱。
- module.exports = {
- library: '[name]',
- libraryTarget: 'window',//var、assign、this、window、global、commonjs、commonjs2、amd、umd……
- }
三、Loader
webpack只能理解JavaScript和JSON文件,通過loader讓webpack能夠去處理其它類型的文件,并將它們轉(zhuǎn)換為有效 模塊,以供應(yīng)用程序使用,以及被添加到依賴圖中。
3.1 樣式資源
對于css和less這樣的樣式資源,webpack不能直接進(jìn)行處理,所以需要經(jīng)過webpack翻譯后才可以使用。此外不同瀏覽器對CSS的支持不同,為了CSS解決兼容性問題,可借助postcss-loader進(jìn)行處理。
- module.export = {
- ……
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [
- //創(chuàng)建style標(biāo)簽,將js中的樣式資源插入到html文件中。
- 'style-loader',
- // 將css文件變成commonjs模塊加載到j(luò)s中
- 'css-loader',
- 'postcss-loader',
- ]
- },
- {
- test: /\.less$/,
- use: [
- 'style-loader',
- 'css-loader',
- // 將less文件編譯成css文件
- 'less-loader',
- ]
- }
- ]
- }
- }
3.2 圖片資源
對于圖片資源來說,主要可以分為html中圖片和非html中圖片。對于url-loader或file-loader能夠處理js、css等中的圖片資源,但是不能直接處理html中的圖片資源,所以需要引用html-loader,負(fù)責(zé)引入img,從而能被url-loader進(jìn)行處理。
- module.exports = {
- module: {
- rules: [
- {
- test: /\.(png|jpg|gif)$/,
- loader: 'url-loader',
- options: {
- limit: 8 * 1024,
- name: '[hash:10].[ext]',
- outputPath: 'asset/images'
- }
- },
- {
- test: /\.html/,
- loader: 'html-loader',
- },
- ]
- }
- }
3.3 js文件
因?yàn)槊總€(gè)人寫代碼的風(fēng)格不同,為了統(tǒng)一js文件的風(fēng)格,規(guī)范代碼,可以采用eslint-loader進(jìn)行處理。
- module.exports = {
- ……
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- // 優(yōu)先執(zhí)行
- enfore: 'pre',
- loader: 'eslint-loader',
- options: {
- // fix: true
- }
- }
- ]
- }
- }
此處可以用比較權(quán)威的Airbnb來進(jìn)行語法檢查,需要在package.json中添加:
- "eslintConfig": {
- "extends": "airbnb-base",
- "env": {
- "browser": true
- }
- }
不同瀏覽器對js代碼的支持性不同,所以需要對js代碼進(jìn)行兼容性處理,可以利用babel-loader,配置方式主要有三種:
(1) 基本js兼容性處理-->@babel/preset-env
問題:只能轉(zhuǎn)換基本語法,如Promise不能轉(zhuǎn)換
(2)全部js兼容性處理--> @babel/polyfill
對于這個(gè)文件,只需要在js文件中直接引入即可 import '@babel/polyfill'; 這會將js有兼容性的東西全部帶進(jìn)來。
問題:我只要解決部分兼容性問題,但是將所有兼容性代碼全部引入,導(dǎo)致文件體積太大了
(3)需要做兼容性處理的就做:按需加載 --> core-js
此時(shí)要把第二種方案的代碼注釋掉。
- module.exports = {
- ……
- module: {
- rules: [
- {
- test: /\.js$/,
- exclude: /node_modules/,
- loader: 'babel-loader',
- options: {
- // 預(yù)設(shè):指示babel做怎么樣的兼容性處理
- presets: [
- '@babel/preset-env',
- {
- // 按需加載
- useBuiltIns: 'usage',
- // 指定core-js版本
- corejs: {
- version: 3
- },
- // 指定兼容性做到哪個(gè)版本瀏覽器
- targets: {
- chrome: '60',
- firefox: '60',
- edge: '17',
- safari: '10',
- }
- }
- ]
- }
- }
- ]
- }
- }
3.4 其它資源
對于不需要進(jìn)行優(yōu)化、壓縮等進(jìn)行處理的文件,例如字體圖標(biāo)、SVG等,可以直接被引入使用,這個(gè)時(shí)候用file-loader直接處理即可。
- module.exports = {
- module: {
- rules: [
- {
- exclude: /\.(css|js|html|less|jpg|png|gif)$/,
- loader: 'file-loader',
- options: {
- name: '[hash:10].[ext]',
- }
- }
- ]
- }
- }
四、Plugin
插件目的是解決loader無法實(shí)現(xiàn)的其他事,可用于執(zhí)行范圍更廣的任務(wù),為webpack帶來很大的靈活性。
4.1 HTML文件
為了簡化HTML文件的創(chuàng)建,方便為webpack包提供服務(wù),所以可以利用html-webpack-plugin插件。通過利用該插件可以自動(dòng)引入JS、CSS等文件,可以對HTM代碼進(jìn)行壓縮;此外,該插件還可以利用提供的HTML模板。
- module.exports = {
- plugins: [
- // html-webpack-plugin插件,默認(rèn)會創(chuàng)建一個(gè)空的HTML,自動(dòng)引入打包輸出的所有資源(JS、CSS)
- new HtmlWebpackPlugin({
- // 需要有結(jié)構(gòu)的HTML文件,可以通過配置template,復(fù)制該html文件,并自動(dòng)引入自動(dòng)引入打包輸出的所有資源(JS、CSS)
- template: './src/index.html',
- // 壓縮html代碼
- minify: {
- // 移除空格
- collapseWhitespace: true,
- // 移除注釋
- removeComments: true,
- }
- })
- ],
- }
4.2 CSS文件
對于CSS文件,利用插件主要需要處理三個(gè)方面:提取CSS文件、兼容性處理(配合postcss-loader)和對CSS文件進(jìn)行壓縮。
- 提取CSS文件:mini-css-extract-plugin
- 兼容性處理:post-preset-env
- 壓縮:optimize-css-assets-webpack-plugin
- module.exports = {
- ……
- module: {
- rules: [
- {
- test: /\.css$/,
- use: [
- // 'style-loader',
- MiniCssExtractPlugin.loader,// 用這個(gè)loader取代style-loader。作用:提取js中的css成單獨(dú)文件
- 'css-loader',
- {
- loader: 'postcss-loader',
- options: {
- ident: 'postcss',
- plugins: () => [
- require('postcss-preset-env')()
- ]
- }
- }
- ]
- },
- ]
- },
- plugins: [
- new MiniCssExtractPlugin({
- // 對輸出的css文件進(jìn)行重命名
- filename: 'css/[name].css'
- }),
- // 壓縮css
- new OptimizeCssAssetsWebpackPlugin(),
- ]
- }
五、Mode
指示wenpack使用相應(yīng)模式進(jìn)行配置。
選項(xiàng) | 描述 |
---|---|
development | 會將 DefinePlugin 中 process.env.NODE_ENV 的值設(shè)置為 development。啟用 NamedChunksPlugin 和 NamedModulesPlugin。 |
production | 會將 DefinePlugin 中 process.env.NODE_ENV 的值設(shè)置為 production。啟用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。 |
none | 退出任何默認(rèn)優(yōu)化選項(xiàng) |
本文轉(zhuǎn)載自微信公眾號「前端點(diǎn)線面」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系前端點(diǎn)線面公眾號。