本篇章適合有必定webpack基礎的攻城獅,本人目前是一名學生,處於學習階段,若是有寫的很差的地方歡迎大神指正。javascript
本章主要包含如下幾部份內容:css
Webpack 簡介html
Webpack 初體驗前端
Webpack 開發環境的基本配置vue
Webpack 生產環境的基本配置java
Webpack 優化配置node
Webpack 配置詳情react
Webpack5 使用jquery
你們學完以後若是覺着意猶未盡能夠繼續學習Webpack 從入門到精通-進階篇,進階篇主要講述以下內容:webpack
這邊主要講解了經常使用的Webpack配置,更詳細的配置你們能夠查看官網Webpack官網
下面進入正題
webpack 是一種前端資源構建工具,一個靜態模塊打包器(module bundler)。 在 webpack 看來, 前端的全部資源文件(js/json/css/img/less/...)都會做爲模塊處理。 它將根據模塊的依賴關係進行靜態分析,打包生成對應的靜態資源(bundle)。
入口(Entry)指示 webpack 以哪一個文件爲入口起點開始打包,分析構建內部依賴圖。
輸出(Output)指示 webpack 打包後的資源 bundles 輸出到哪裏去,以及如何命名。
Loader:讓 webpack 可以去處理那些非 JS 的文件,好比樣式文件、圖片文件(webpack 自身只理解JS)
插件(Plugins):能夠用於執行範圍更廣的任務。插件的範圍包括,從打包優化和壓縮,一直到從新定義環境中的變量等。
模式(Mode):指示 webpack 使用相應模式的配置。
選項 | 描述 | 特色 |
---|---|---|
development | 會將 DefinePlugin 中 process.env.NODE_ENV 的值設置爲 development。啓用 NamedChunksPlugin 和 NamedModulesPlugin。 | 能讓代碼本地調試運行的環境 |
production | 會將 DefinePlugin 中 process.env.NODE_ENV 的值設置爲 production。啓用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。 | 能讓代碼優化上線運行的環境 |
輸入指令:npm init 2. 下載並安裝 webpack 輸入指令: npm install webpack webpack-cli -g(全局安裝)(即便之前安裝過,如今也是能夠安裝的,會對之前的進行更新) npm install webpack webpack-cli -D(本地安裝)
開發環境指令:webpack src/js/index.js -o build/js/built.js --mode=development 功能:webpack 可以編譯打包 js 和 json 文件,而且能將 es6 的模塊化語法轉換成 瀏覽器能識別的語法。 生產環境指令:webpack src/js/index.js -o build/js/built.js --mode=production 功能:在開發配置功能上多一個功能,壓縮代碼。 3. 結論 webpack 可以編譯打包 js 和 json 文件。 能將 es6 的模塊化語法轉換成瀏覽器能識別的語法。 能壓縮代碼。 4. 問題 不能編譯打包 css、img 等文件。 不能將 js 的 es6 基本語法轉化爲 es5 如下語法。
const { resolve } = require('path'); // node 內置核心模塊,用來處理路徑問題。
module.exports = {
entry: './src/js/index.js',
// 入口文件
output: {
// 輸出配置
filename: './built.js',
// 輸出文件名
path: resolve(__dirname, 'build/js')// 輸出文件路徑配置
},
mode: 'development'//開發環境
};
複製代碼
npm i css-loader style-loader less-loader less -D
/* webpack.config.js webpack的配置文件(src裏面寫項目代碼,webpack寫配置代碼) 做用: 指示 webpack 幹哪些活(當你運行 webpack 指令時,會加載裏面的配置) 全部構建工具都是基於nodejs平臺運行的~模塊化默認採用commonjs。 */
// resolve用來拼接絕對路徑的方法
const {
resolve
} = require('path');
module.exports = {
// webpack配置
// 入口起點
entry: './src/index.js',
// 輸出(輸出到build文件夾下面的built.js文件中)
output: {
// 輸出文件名
filename: 'built.js',
// 輸出路徑
// __dirname nodejs的變量,表明當前文件的目錄絕對路徑(表示的是與當前webpack.config.js平級的build文件夾)
path: resolve(__dirname, 'build')
},
// loader的配置
module: {
rules: [
// 詳細loader配置
// 不一樣文件必須配置不一樣loader處理
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader進行處理
use: [
// use數組中loader執行順序:從右到左,從下到上 依次執行
// 建立style標籤,將js中的樣式資源插入進行,添加到head中生效
'style-loader',
// 將css文件變成commonjs模塊加載js中,裏面內容是樣式字符串
'css-loader'
]
}, {
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 將less文件編譯成css文件
// 須要下載 less-loader和less
'less-loader'
]
}
]
},
// plugins的配置
plugins: [
// 詳細plugins的配置
],
// 模式(表示使用什麼模式)
mode: 'development', // 開發模式
// mode: 'production'
}
/* 執行的步驟:只分析less(安裝loader:style-loader css-loader less-loader less)(css只須要安裝前面兩個loader) 1. 根據entry找到入口文件'./src/index.js' 2. 發現入口文件中引入了.less文件,而.less文件不是js或者json文件,去找module的rules裏面尋找less的loader 3. 找到test: /\.less$/,執行該對象中的rules數組中的代碼(從右到左,從下到上 依次執行) 4. 經過less-loader將less文件編譯成css文件 5. 經過css-loader將css文件變成commonjs模塊加載js中,裏面內容是樣式字符串 6. 經過style-loader建立style標籤,將js中的樣式資源插入進行,添加到head中生效 7. 將代碼添加到出口文件與當前webpack.config.js平級的build文件夾下面的built.js文件中 */
複製代碼
npm install --save-dev html-webpack-plugin
/* loader: 1. 下載 2. 使用(配置loader) plugins: 1. 下載 2. 引入 3. 使用 */
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
]
},
plugins: [
// plugins的配置
// html-webpack-plugin
// 功能:默認會建立一個空的HTML,自動引入打包輸出的全部資源(JS/CSS)
// 需求:須要有結構的HTML文件,須要添加一個template
new HtmlWebpackPlugin({
// 複製 './src/index.html' 文件,並自動引入打包輸出的全部資源(JS/CSS)
template: './src/index.html'
})
],
mode: 'development'
};
/* 執行的步驟:html(安裝plugin:html-webpack-plugin) 1. 根據entry找到入口文件'./src/index.js' 2. 發現入口文件中引入了html文件,而html文件不是js或者json文件,去plugins數組中找到HtmlWebpackPlugin插件 3. 複製template選項中的文件, 4. 經過less-loader將less文件編譯成css文件,自動引入打包輸出的全部資源(JS/CSS)(JS文件經過script標籤引入,CSS文件經過link標籤引入)(不須要本身再引用了,不然重複引入會出問題的) */
複製代碼
npm install --save-dev html-loader url-loader file-loader
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.less$/,
// 要使用多個loader處理用use
use: ['style-loader', 'css-loader', 'less-loader']
}, {
// 問題:默認處理不了html中img圖片
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
// 使用一個loader
// 下載 url-loader file-loader(url-loader依賴於file-loader)
loader: 'url-loader',
options: {
// 圖片大小小於8kb,就會被base64處理(一般小圖片(8-12kb)使用limit進行這種處理,若是有9kb的圖片,咱們能夠將limit寫成10 * 1024)
// 優勢: 減小請求數量(減輕服務器壓力)
// 缺點:圖片體積會更大(文件請求速度更慢)
limit: 8 * 1024,
// 問題:由於url-loader默認使用es6模塊化解析,而html-loader引入圖片是commonjs
// 解析時會出問題:[object Module]
// 解決:關閉url-loader的es6模塊化,使用commonjs解析
esModule: false,
// 給圖片進行重命名
// [hash:10]取圖片的hash的前10位
// [ext]取文件原來擴展名
name: '[hash:10].[ext]'
}
}, {
test: /\.html$/,
// 處理html文件的img圖片,而不是處理html文件的,html文件是用HtmlWebpackPlugin處理的(負責引入img,從而能被url-loader進行處理)
loader: 'html-loader'
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
/* 執行的步驟:打包圖片資源(安裝loader:url-loader file-loader html-loader) 1. 根據entry找到入口文件'./src/index.js' 2. 發現入口文件中引入了jpg|png|gif文件,而jpg|png|gif文件不是js或者json文件,去找module的rules裏面尋找jpg|png|gif的loader 3. 找到test: /\jpg|png|gifs$/,執行該對象中的rules數組中的代碼 4. 經過options-->limit對體積進行限制 5. 這種方式只能處理樣式中引入的圖片,不能處理html中引入的圖片,若是要處理htnl中引入的資源,須要使用html-loader 6. 處理html中引入的圖片須要找到test: /\jpg|png|gifs$/,執行裏面的html-loader 7. 可是解析時圖片的名稱會出現[object Module]問題,這是由於url-loader默認使用es6模塊化解析,而html-loader引入圖片是commonjs,使用esModule: false關閉url-loader的es6模塊化,使用commonjs解析便可 8. 使用name: '[hash:10].[ext]'給圖片進行重命名 */
複製代碼
npm install --save-dev file-loader
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其餘資源(除了html/js/css資源之外的資源)
{
// 排除css/js/html資源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其餘資源(除了html/js/css資源之外的資源)
{
// 排除css/js/html資源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
// 要安裝 webpack-dev-server(由於是本地安裝,因此須要使用npx webpack-dev-server啓動,webpack咱們使用的全局安裝,因此啓動的時候不須要使用npx)
// 開發服務器 devServer:用來自動化(自動編譯,自動打開瀏覽器,自動刷新瀏覽器~~)
// 特色:只會在內存中編譯打包,不會有任何輸出
// 啓動devServer指令爲:npx webpack-dev-server
devServer: {
// 項目構建後路徑
contentBase: resolve(__dirname, 'build'),
// 啓動gzip壓縮(使得打包後的代碼體積更小)
compress: true,
// 端口號
port: 3000,
// 自動打開瀏覽器
open: true
}
};
複製代碼
上面3.2-3.6下載的loader/plugin文件
/* 開發環境配置:能讓代碼運行 運行項目指令: webpack 會將打包結果輸出出去 npx webpack-dev-server 只會在內存中編譯打包,沒有輸出 全部的代碼打包輸出到js/built.js文件中 隨着咱們的資源愈來愈多,咱們還須要將代碼分類打包,即是在每個loader中使用outputPath: build文件夾下面的須要放置打包文件的文件夾名 css、less等文件不須要設置專門的outputPath,由於它們是直接打包成字符串放進js文件中的 */
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
// 處理less資源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}, {
// 處理css資源
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 關閉es6模塊化
esModule: false,
outputPath: 'imgs'
}
}, {
// 處理html中img資源
test: /\.html$/,
loader: 'html-loader'
}, {
// 處理其餘資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true
}
};
複製代碼
npm install --save-dev mini-css-extract-plugin
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//使用這個插件的做用:style樣式不是放在style標籤中的,而是經過link的方式使用
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: [
// 'style-loader'做用:建立style標籤,將樣式放入,
// 這個loader取代style-loader。做用:提取js中的css成單獨文件
MiniCssExtractPlugin.loader,
// 將css文件整合到js文件中
'css-loader'
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
// 對輸出的css文件進行重命名
filename: 'css/built.css'
})
],
mode: 'development'
};
複製代碼
npm install --save-dev postcss-loader postcss-preset-env
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 設置nodejs環境變量
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
/* css兼容性處理:postcss --> postcss-loader postcss-preset-env(做用:postcss-preset-env幫助postcss識別環境從而加載對應的配置,從而使得代碼兼容每個瀏覽器的版本) postcss-preset-env: 幫postcss找到package.json中browserslist裏面的配置,經過配置加載指定的css兼容性樣式 //browserslist要寫在package.json中 "browserslist": { // 開發環境 --> 設置node環境變量:process.env.NODE_ENV = development "development": [ "last 1 chrome version",//兼容最近的版本 "last 1 firefox version", "last 1 safari version" ], // 生產環境:默認是看生產環境 "production": [ ">0.2%", "not dead",//不用已經死的瀏覽器 "not op_mini all"//不用op_mini版本的瀏覽器 ] } */
// 使用loader的默認配置
// 'postcss-loader',
// 修改loader的配置,寫成下面的對象的形式
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
})
],
mode: 'development'
};
複製代碼
"browserslist": {
// 開發環境 --> 設置node環境變量:process.env.NODE_ENV = development
"development": [
"last 1 chrome version",//兼容最近的版本
"last 1 firefox version",
"last 1 safari version"
],
// 生產環境:默認是看生產環境
"production": [
">0.2%",
"not dead",//不用已經死的瀏覽器
"not op_mini all"//不用op_mini版本的瀏覽器
]
}
複製代碼
npm install --save-dev optimize-css-assets-webpack-plugin
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// 設置nodejs環境變量
// process.env.NODE_ENV = 'development';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
// 壓縮css
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development'
};
複製代碼
npm install --save-dev eslint-loader eslint eslint-config-airbnb-base eslint-plugin-import
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
/* 語法檢查: eslint-loader eslint 注意:只檢查本身寫的源代碼,第三方的庫是不用檢查的 設置檢查規則: package.json中eslintConfig中設置~ "eslintConfig": { "extends": "airbnb-base" } airbnb --> eslint-config-airbnb-base eslint-plugin-import eslint */
{
test: /\.js$/,
exclude: /node_modules/, //排除第三方的代碼,只檢查本身的代碼
loader: 'eslint-loader',
options: {
// 自動修復eslint的錯誤
fix: true
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
/* 1. 語法檢查咱們須要使用eslint-loader eslint,因此先下載eslint-loader eslint 2. 使用exclude: /node_modules/排除第三方的代碼,只檢查本身的代碼 3. 語法檢查一般採用airbnb(能夠在網站https://github.com/topics/javascript中找出進行詳細的看裏面的介紹,咱們想要將airbnb庫與eslint結合在一塊兒的話,去npmjs網站中搜索elsint找到eslint-config-airbnb-base,點進去根據需求下載安裝便可,eslint-config-airbnb是能夠檢測react代碼的,用到react編寫代碼的時候可使用這個庫),所以須要下載eslint-config-airbnb-base eslint-plugin-import eslint 4. 在package.json中配置語法檢查採用的標準 5. 檢查出現語法問題的代碼使用fix: true實現自動修復eslint出現的語法錯誤 6. 若是在代碼中使用console.log()等語法,eslint會出現提示警告,此時咱們能夠在console.log()上一行加上一行註釋// eslint-disable-next-line表示下一行eslint全部規則都失效(下一行不進行eslint檢查) */
複製代碼
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
}
複製代碼
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/polyfill core-js
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
/* js兼容性處理:安裝babel-loader @babel/core 兩個庫 1. 基本js兼容性處理 --> 安裝@babel/preset-env庫 問題:只能轉換基本語法,如promise高級語法不能轉換 2. 須要作兼容性處理的就作:按需加載 --> 安裝core-js庫並在presets裏面做以下配置 前兩步驟是咱們經常使用的兼容性處理的方式 3. 所有js兼容性處理 --> 安裝babel-loader @babel/core @babel/preset-env @babel/polyfill 不須要進行配置,只須要在主入口文件中引入 @babel/polyfill便可(import '@babel/polyfill') 問題:我只要解決部分兼容性問題,可是將全部兼容性代碼所有引入,體積太大了,因此咱們不使用這種方式~ */
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 預設:指示babel作怎麼樣的兼容性處理
presets: [
[
'@babel/preset-env', {
// 按需加載
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3
},
// 指定兼容性作到哪一個版本瀏覽器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
// 生產環境下會自動壓縮js代碼//內部會自動加載一些插件
mode: 'production'
};
複製代碼
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
// 壓縮html代碼
minify: {
// 移除空格
collapseWhitespace: true,
// 移除註釋
removeComments: true
}
})
],
mode: 'production'
};
複製代碼
下載前面的全部的安裝包
const {
resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 定義nodejs環境變量:決定使用browserslist的哪一個環境
process.env.NODE_ENV = 'production';
// 複用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader', {
// 還須要在package.json中定義browserslist
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: [...commonCssLoader]
}, {
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
/* 正常來說,一個文件只能被一個loader處理。 當一個文件要被多個loader處理,那麼必定要指定loader執行的前後順序: 先執行eslint 在執行babel */
{
// 在package.json中eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
// 優先執行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
}, {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]
]
}
}, {
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production'
};
複製代碼
/* 1.爲何要啓用熱更新? 當咱們改變頁面中的css文件的時候會觸發整個文件包括js文件都會從新打包進行更新,這樣會形成慢的打包速度,這是咱們不想要的結果,因此要進行熱更新,只對修改的那個文件進行從新打包,進行更新。 2.HMR: hot module replacement 熱模塊替換 / 模塊熱替換(在devServer中將hot設置爲true即爲開啓) 做用:一個模塊發生變化,只會從新打包這一個模塊(而不是打包全部模塊) 極大提高構建速度 樣式文件:可使用HMR功能:由於style-loader內部實現了~ js文件:默認不能使用HMR功能 --> 須要修改js代碼,添加支持HMR功能的代碼 注意:HMR功能對js的處理,只能處理非入口js文件的其餘文件。 html文件: 默認不能使用HMR功能.同時會致使問題:html文件不能熱更新了~ (不用作HMR功能,由於只有一個html文件,只要裏面的內容發生變化,文件是必定要更新的) 解決:修改entry入口,將html文件引入,這樣才能夠生效 */
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['./src/js/index.js', './src/index.html'],
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
// 處理less資源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}, {
// 處理css資源
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 關閉es6模塊化
esModule: false,
outputPath: 'imgs'
}
}, {
// 處理html中img資源
test: /\.html$/,
loader: 'html-loader'
}, {
// 處理其餘資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true,
// 開啓HMR功能
// 當修改了webpack配置,新配置要想生效,必須重啓webpack服務
hot: true
}
};
複製代碼
if (module.hot) {
// 一旦 module.hot 爲true,說明開啓了HMR功能。 --> 讓HMR功能代碼生效
module.hot.accept('./print.js', function() {
// 方法會監聽 print.js 文件的變化,一旦發生變化,其餘模塊不會從新打包構建。
// 會執行後面的回調函數
//此處至關因而監聽到print.js發生了變化,執行print()函數
print();
});
}
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: ['./src/js/index.js', './src/index.html'],
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
// 處理less資源
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}, {
// 處理css資源
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
// 處理圖片資源
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
// 關閉es6模塊化
esModule: false,
outputPath: 'imgs'
}
}, {
// 處理html中img資源
test: /\.html$/,
loader: 'html-loader'
}, {
// 處理其餘資源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
outputPath: 'media'
}
}
]
},
plugins: [
// plugins的配置
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true,
port: 3000,
open: true,
hot: true
},
devtool: 'eval-source-map' //使用:直接加上這句話便可
};
/* source-map: 一種 提供源代碼到構建後代碼映射 技術 (若是構建後代碼出錯了,經過映射能夠追蹤源代碼錯誤) [inline-|hidden-|eval-][nosources-][cheap-[module-]]source-map source-map:外部 錯誤代碼準確信息 和 源代碼的錯誤位置 inline-source-map:內聯 只生成一個內聯source-map 錯誤代碼準確信息 和 源代碼的錯誤位置 hidden-source-map:外部 錯誤代碼錯誤緣由,可是沒有錯誤位置 不能追蹤源代碼錯誤,只能提示到構建後代碼的錯誤位置 eval-source-map:內聯 每個文件都生成對應的source-map,都在eval 錯誤代碼準確信息 和 源代碼的錯誤位置 nosources-source-map:外部 錯誤代碼準確信息, 可是沒有任何源代碼信息 cheap-source-map:外部 錯誤代碼準確信息 和 源代碼的錯誤位置 只能精確的行 cheap-module-source-map:外部 錯誤代碼準確信息 和 源代碼的錯誤位置 module會將loader的source map加入 內聯 和 外部的區別:1. 外部生成了文件,內聯沒有 2. 內聯構建速度更快 開發環境:速度快,調試更友好 速度快(eval>inline>cheap>...) eval-cheap-souce-map(速度最快) eval-source-map 調試更友好 souce-map(調試最好) cheap-module-souce-map cheap-souce-map --> eval-source-map > :eval-cheap-module-souce-map 生產環境:源代碼要不要隱藏? 調試要不要更友好 內聯會讓代碼體積變大,因此在生產環境不用內聯 nosources-source-map 所有隱藏 hidden-source-map 只隱藏源代碼,會提示構建後代碼錯誤信息 --> source-map() / cheap-module-souce-map 最終總結: 開發環境使用:eval-source-map 生產環境使用:source-map() */
複製代碼
const {
resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
process.env.NODE_ENV = 'production';
// 複用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader', {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
// 優先執行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
}, {
// 如下loader只會匹配一個(這樣子便不會只須要一個loader的時候將全部的loader遍歷一遍了,能夠提升速度)
// 注意:不能有兩個配置處理同一種類型文件(好比咱們的bable-loader和eslint-loader都要使用,那麼咱們將eslint-loader提取出來放到oneOf前面,這樣前面的eslint-loader執行完畢以後再從oneOf裏面找到bable-loader執行)
oneOf: [{
test: /\.css$/,
use: [...commonCssLoader]
}, {
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
/* 正常來說,一個文件只能被一個loader處理。 當一個文件要被多個loader處理,那麼必定要指定loader執行的前後順序: 先執行eslint 在執行babel */
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '50'
}
}
]
]
}
}, {
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
}]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production'
};
複製代碼
const {
resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* 緩存: 1. babel緩存 cacheDirectory: true --> 讓第二次打包構建速度更快 2. 文件資源緩存 hash: 每次wepack構建時會生成一個惟一的hash值。 問題: 由於js和css同時使用一個hash值。 若是從新打包,會致使全部緩存失效。(可能我卻只改動一個文件) chunkhash:根據chunk生成的hash值。若是打包來源於同一個chunk,那麼hash值就同樣 問題: js和css的hash值仍是同樣的 由於css是在js中被引入的,因此同屬於一個chunk contenthash: 根據文件的內容生成hash值。不一樣文件hash值必定不同 --> 讓代碼上線運行緩存更好使用(上線代碼的性能優化的) 綜上所述:開啓緩存須要經歷兩個步驟: 1. 設置cacheDirectory: true 2. 在輸出的數組中加上contenthash */
// 定義nodejs環境變量:決定使用browserslist的哪一個環境
process.env.NODE_ENV = 'production';
// 複用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader', {
// 還須要在package.json中定義browserslist
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.[contenthash:10].js', //本節修改的地方
path: resolve(__dirname, 'build')
},
module: {
rules: [{
// 在package.json中eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
// 優先執行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
}, {
oneOf: [{
test: /\.css$/,
use: [...commonCssLoader]
}, {
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '50'
}
}
]
],
// 開啓babel緩存
// 第二次構建時,會讀取以前的緩存
cacheDirectory: true // 本節修改的位置
}
}, {
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
}]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css' //本節修改的地方
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production',
devtool: 'source-map'
};
複製代碼
3. 運行指令:webpack
const {
resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* tree shaking:去除無用代碼,使得體積更小 前提:1. 必須使用ES6模塊化 2. 開啓production環境 做用: 減小代碼體積 在package.json中配置 "sideEffects": false 全部代碼都沒有反作用(均可以進行tree shaking) 問題:可能會把css / @babel/polyfill (反作用)文件幹掉,因此採用下面的一行形式 "sideEffects": ["*.css", "*.less"](加上這句話表示不移除css和less文件) */
process.env.NODE_ENV = 'production';
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader', {
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
}, {
oneOf: [{
test: /\.css$/,
use: [...commonCssLoader]
}, {
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
}, {
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', {
useBuiltIns: 'usage',
corejs: {
version: 3
},
targets: {
chrome: '60',
firefox: '50'
}
}
]
],
cacheDirectory: true
}
}, {
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
}, {
test: /\.html$/,
loader: 'html-loader'
}, {
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}]
}]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production',
devtool: 'source-map'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 單入口打包輸出一個文件,多入口打包輸出多個文件,有幾個入口便打包輸出多少個文件
// 單入口(單頁面應用程序使用單入口)(開發時單入口應用使用的多)
// entry: './src/js/index.js',
entry: {
// 多入口:有一個入口,最終輸出就有一個bundle(多頁面應用程序使用多入口)
index: './src/js/index.js',
test: './src/js/test.js'
},
output: {
// [name]:取文件名(好比上面的entry中名稱爲index,那麼輸出的文件名首部會有index名稱)
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
mode: 'production'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 單入口
// entry: './src/js/index.js',
entry: {
index: './src/js/index.js',
test: './src/js/test.js'
},
output: {
// [name]:取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
/* 1. 能夠將node_modules中代碼單獨打包一個chunk最終輸出(將別人的第三方的東西單獨打包,將本身寫的東西單獨打包) 2. 自動分析多入口chunk中,有沒有公共的文件。若是有會打包成單獨一個chunk 3. 這種單入口的形式不常使用 */
optimization: {
splitChunks: {
chunks: 'all'
}
},
mode: 'production'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 單入口
entry: './src/js/index.js',
output: {
// [name]:取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
/* 1. 單入口的這種形式常用,實現功能:單入口打包輸出多個出口文件,從而使得多個文件並行運行,增長運行速度 2. 這種方式能夠將node_modules中代碼單獨打包一個chunk最終輸出,將入口文件打包輸出一個出口文件,若是想要將某個單獨的文件也打包輸出爲一個文件,則須要進行如下配置: 1. optimization配置 2.在打包的出口文件中對須要單獨打包的文件輸入相關代碼 */
optimization: {
splitChunks: {
chunks: 'all'
}
},
mode: 'production'
};
複製代碼
function sum(...args) {
return args.reduce((p, c) => p + c, 0);
}
/* 經過js代碼,讓某個文件被單獨打包成一個chunk import動態導入語法:能將某個文件單獨打包 webpackChunkName: 'test'的做用是命名輸出的打包名稱,不然打包名稱會根據每次打包輸出的id進行命名,每次打包輸出的id不同,名稱也不同 */
import ( /* webpackChunkName: 'test' */ './test')
.then(({ mul, count }) => {
// 文件加載成功~
// eslint-disable-next-line
console.log(mul(2, 5));
})
.catch(() => {
// eslint-disable-next-line
console.log('文件加載失敗~');
});
// eslint-disable-next-line
console.log(sum(1, 2, 3, 4));
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 單入口
entry: './src/js/index.js',
output: {
// [name]:取文件名
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
],
/* 1. 單入口的這種形式常用,實現功能:單入口打包輸出多個出口文件,從而使得多個文件並行運行,增長運行速度 2. 這種方式能夠將node_modules中代碼單獨打包一個chunk最終輸出,將入口文件打包輸出一個出口文件,若是想要將某個單獨的文件也打包輸出爲一個文件,則須要進行如下配置: 1. optimization配置 2.在打包的出口文件中對須要單獨打包的文件輸入相關代碼 */
optimization: {
splitChunks: {
chunks: 'all'
}
},
mode: 'production'
};
複製代碼
console.log('index.js文件被加載了~');
// import { mul } from './test'; 屬於正常加載
document.getElementById('btn').onclick = function() {
// 懶加載~:當文件須要使用時才加載~
// 預加載 webpackPrefetch: true:會在使用以前,提早加載js文件
// 正常加載能夠認爲是並行加載(同一時間加載多個文件)
// 預加載 prefetch:等其餘資源加載完畢,瀏覽器空閒了,再偷偷加載資源(兼容性比較差的)(檢測是不是預加載了能夠經過打開控制檯,查看網絡看出是不是提早加載了)
/* 1. 一般狀況下懶加載的第一次加載若是加載的文件比較大的話會加載的時間比較長,給用戶形成阻塞的現象 2. 通常不使用預加載,由於兼容性差了一些,通常使用懶加載 3. 懶加載的實現是基於前面的代碼分割的基礎上的,要進行了前面的代碼分割的配置纔可使用懶加載,這個案例實現的功能是點擊按鈕以後再加載test文件中的js代碼 4. 懶加載第一次可能會慢一點,第二次加載便不會慢了,第一次加載會存入緩存中,第二次加載會直接從緩存中加載 */
import ( /* webpackChunkName: 'test', webpackPrefetch: true */ './test').then(({ mul }) => {
console.log(mul(4, 5));
});
};
複製代碼
npm install --save-dev workbox-webpack-plugin
const {
resolve
} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
/* PWA: 漸進式網絡開發應用程序(離線可訪問) workbox --> workbox-webpack-plugin */
process.env.NODE_ENV = 'production';
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
]
},
plugins: [
new WorkboxWebpackPlugin.GenerateSW({
/* 1. 幫助serviceworker快速啓動 2. 刪除舊的 serviceworker 生成一個 serviceworker 配置文件~ */
clientsClaim: true,
skipWaiting: true
})
],
mode: 'production',
devtool: 'source-map'
};
複製代碼
import { mul } from './test';
import '../css/index.css';
function sum(...args) {
return args.reduce((p, c) => p + c, 0);
}
// eslint-disable-next-line
console.log(mul(2, 3));
// eslint-disable-next-line
console.log(sum(1, 2, 3, 4));
/* 1. eslint不認識 window、navigator全局變量 解決:須要修改package.json中eslintConfig配置 "env": { "browser": true // 支持瀏覽器端全局變量,若是要支持node的全局變量,則寫"node":true } 2. sw代碼必須運行在服務器上 --> nodejs --> npm i serve -g serve -s build 啓動服務器,將build目錄下全部資源做爲靜態資源暴露出去 */
// 註冊serviceWorker
// 處理兼容性問題
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js')
.then(() => {
console.log('sw註冊成功了~');
})
.catch(() => {
console.log('sw註冊失敗了~');
});
});
}
複製代碼
查看註冊的service workers 註冊成功緩存的離線數據
4. 運行指令:webpack
npm install --save-dev thread-loader
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');//
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.[contenthash:10].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
oneOf: [
{
test: /\.css$/,
use: [...commonCssLoader]
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader']
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
/* 開啓多進程打包。 進程啓動大概爲600ms,進程通訊也有開銷。 只有工做消耗時間比較長,才須要多進程打包 */
{
loader: 'thread-loader',
options: {
workers: 2 // 進程2個
}
},
{
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3 },
targets: {
chrome: '60',
firefox: '50'
}
}
]
],
cacheDirectory: true
}
}
]
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[ext]',
outputPath: 'imgs',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media'
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/built.[contenthash:10].css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
}),
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
skipWaiting: true
})
],
mode: 'production',
devtool: 'source-map'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'production',
externals: {
// 拒絕jQuery被打包進來,做用: 假如說咱們的jequery使用的是CDN連接,那麼打包的時候jquery不會被打包進來,直接使用CDN連接
jquery: 'jQuery'
}
};
複製代碼
/* 使用dll技術,對某些庫(第三方庫:jquery、react、vue...)進行單獨打包 當你運行 webpack 時,默認查找 webpack.config.js 配置文件 需求:須要運行 webpack.dll.js 文件 --> webpack --config webpack.dll.js */
const {
resolve
} = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
// 最終打包生成的[name] --> jquery
// ['jquery'] --> 要打包的庫是jquery
jquery: ['jquery'],
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'dll'),
library: '[name]_[hash]' // 打包的庫裏面向外暴露出去的內容叫什麼名字
},
plugins: [
// 打包生成一個 manifest.json --> 提供和jquery映射
new webpack.DllPlugin({
name: '[name]_[hash]', // 映射庫的暴露的內容名稱
path: resolve(__dirname, 'dll/manifest.json') // 輸出文件路徑
})
],
mode: 'production'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 告訴webpack哪些庫不參與打包,同時使用時的名稱也得變~
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, 'dll/manifest.json')
}),
// 將某個文件打包輸出去,並在html中自動引入該資源
new AddAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, 'dll/jquery.js')
})
],
mode: 'production'
};
/* 首先要在webpack.dll.js與webpack.config.js中引入webpack插件 1. 在webpack.dll.js文件中的寫入咱們須要打包的庫以及打包的庫輸出的名字爲何(實現功能:第一次打包以後只要jquery庫名稱不變,下一次不須要在從新打包了,直接使用,提升構建速度)(不只僅是jquery庫,各類庫都要引入) 2. plugin中生成的manifest.json文件表示了jquery的映射關係 3. webpack.config.js中使用DllReferencePlugin告訴webpack哪些文件不須要再從新打包 4. webpack.config.js中使用AddAssetHtmlWebpackPlugin將ebpack.dll.js中打包的資源在html中自動引入 */
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
/* entry: 入口起點 1. string --> './src/index.js'(用的多) 單入口 打包造成一個chunk。 輸出一個bundle文件。 此時chunk的名稱默認是 main 2. array --> ['./src/index.js', './src/add.js'](通常不用這種形式) 多入口 全部入口文件最終只會造成一個chunk, 輸出出去只有一個bundle文件。 --> 只有在HMR功能中讓html熱更新生效~ 3. object(用的多) 多入口 有幾個入口文件就造成幾個chunk,輸出幾個bundle文件 此時chunk的名稱是 key --> 特殊用法 { // 全部入口文件最終只會造成一個chunk, 輸出出去只有一個bundle文件。 index: ['./src/index.js', './src/count.js'], // 造成一個chunk,輸出一個bundle文件。 add: './src/add.js' } */
module.exports = {
entry: {
index: ['./src/index.js', './src/count.js'],
add: './src/add.js'
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'build')
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
複製代碼
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
// 文件名稱(指定名稱+目錄)
filename: 'js/[name].js',
// 輸出文件目錄(未來全部資源輸出的公共目錄)
path: resolve(__dirname, 'build'),
// 全部資源引入公共路徑前綴 --> 'imgs/a.jpg' --> '/imgs/a.jpg'
publicPath: '/',
chunkFilename: 'js/[name]_chunk.js', // 非入口chunk的名稱
// library: '[name]', // 整個庫向外暴露的變量名
// libraryTarget: 'window' // 變量名添加到哪一個上 browser
// libraryTarget: 'global' // 變量名添加到哪一個上 node
// libraryTarget: 'commonjs'
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
複製代碼
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
{
test: /\.css$/,
// 多個loader用use
use: ['style-loader', 'css-loader']
},
{
test: /\.js$/,
// 排除node_modules下的js文件
exclude: /node_modules/,
// 只檢查 src 下的js文件
include: resolve(__dirname, 'src'),
// 優先執行
enforce: 'pre',
// 延後執行
// enforce: 'post',
// 單個loader用loader
loader: 'eslint-loader',
options: {}
},
{
// 如下配置只會生效一個
oneOf: []
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development'
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development',
// 解析模塊的規則
resolve: {
// 配置解析模塊路徑別名: 優勢簡寫路徑 缺點路徑沒有提示
alias: {
$css: resolve(__dirname, 'src/css')
},
// 配置省略文件路徑的後綴名
extensions: ['.js', '.json', '.jsx', '.css'],
// 告訴 webpack 解析模塊是去找哪一個目錄(不寫這個的話,他會一層一層的往上面找,直到找到位置)
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
}
};
複製代碼
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'development',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
devServer: {
// 運行代碼的目錄
contentBase: resolve(__dirname, 'build'),
// 監視 contentBase 目錄下的全部文件,一旦文件變化就會 reload
watchContentBase: true,
watchOptions: {
// 監視的時候忽略文件
ignored: /node_modules/
},
// 啓動gzip壓縮,體積小
compress: true,
// 端口號
port: 5000,
// 域名
host: 'localhost',
// 自動打開瀏覽器
open: true,
// 開啓HMR功能
hot: true,
// 不要顯示啓動服務器日誌信息
clientLogLevel: 'none',
// 除了一些基本啓動信息之外,其餘內容都不要顯示
quiet: true,
// 若是出錯了,不要全屏提示~,只須要在日誌中打印便可
overlay: false,
// 服務器代理 --> 解決開發環境跨域問題
proxy: {
// 一旦devServer(5000)服務器接受到 /api/xxx 的請求,就會把請求轉發到另一個服務器(3000)
'/api': {
target: 'http://localhost:3000',
// 發送請求時,請求路徑重寫:將 /api/xxx --> /xxx (去掉/api)
pathRewrite: {
'^/api': ''
}
}
}
}
};
複製代碼
const {
resolve
} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserWebpackPlugin = require('terser-webpack-plugin')
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/[name].[contenthash:10].js',
path: resolve(__dirname, 'build'),
chunkFilename: 'js/[name].[contenthash:10]_chunk.js'
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
plugins: [new HtmlWebpackPlugin()],
mode: 'production',
resolve: {
alias: {
$css: resolve(__dirname, 'src/css')
},
extensions: ['.js', '.json', '.jsx', '.css'],
modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
},
optimization: {
splitChunks: {
chunks: 'all'
// 默認值,能夠不寫,基本上不修改~
/* minSize: 30 * 1024, // 分割的chunk最小爲30kb,小於30kb的不分割,大於30kb才分割 maxSiza: 0, // 最大沒有限制 minChunks: 1, // 要提取的chunk最少被引用1次 maxAsyncRequests: 5, // 按需加載時並行加載的文件的最大數量 maxInitialRequests: 3, // 入口js文件最大並行請求數量 automaticNameDelimiter: '~', // 名稱鏈接符 name: true, // 可使用命名規則 cacheGroups: { // 分割chunk的組 // node_modules文件會被打包到 vendors 組的chunk中。--> vendors~xxx.js // 知足上面寫的公共規則,如:大小超過30kb,至少被引用一次。 vendors: { test: /[\\/]node_modules[\\/]/, // 優先級 priority: -10 }, default: { // 要提取的chunk最少被引用2次 minChunks: 2, // 優先級 priority: -20, // 若是當前要打包的模塊,和以前已經被提取的模塊是同一個,就會複用,而不是從新打包模塊 reuseExistingChunk: true } }*/
},
// 將當前模塊的記錄其餘模塊的hash單獨打包爲一個文件 runtime
// 解決:修改a文件致使b文件的contenthash變化
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`
},
minimizer: [
// 配置生產環境的壓縮方案:js和css
new TerserWebpackPlugin({
// 開啓緩存
cache: true,
// 開啓多進程打包
parallel: true,
// 啓動source-map
sourceMap: true
})
]
}
};
複製代碼
此版本重點關注如下內容:
早期,webpack 的目標是容許在瀏覽器中運行大多數 node.js 模塊,可是模塊格局發生了變化,許多模塊用途如今主要是爲前端目的而編寫的。webpack <= 4 附帶了許多 node.js 核心模塊的 polyfill,一旦模塊使用任何核心模塊(即 crypto 模塊),這些模塊就會自動應用。
儘管這使使用爲 node.js 編寫的模塊變得容易,但它會將這些巨大的 polyfill 添加到包中。在許多狀況下,這些 polyfill 是沒必要要的。
webpack 5 會自動中止填充這些核心模塊,並專一於與前端兼容的模塊。
遷移:
添加了用於長期緩存的新算法。在生產模式下默認狀況下啓用這些功能。
chunkIds: "deterministic", moduleIds: "deterministic"
你能夠不用使用 import(/* webpackChunkName: "name" */ "module")
在開發環境來爲 chunk 命名,生產環境仍是有必要的
webpack 內部有 chunk 命名規則,再也不是以 id(0, 1, 2)命名了
// inner.js
export const a = 1;
export const b = 2;
// module.js
import * as inner from './inner';
export { inner };
// user.js
import * as module from './module';
console.log(module.inner.a);
複製代碼
在生產環境中, inner 模塊暴露的 b
會被刪除
import { something } from './something';
function usingSomething() {
return something;
}
export function test() {
return usingSomething();
}
複製代碼
當設置了"sideEffects": false
時,一旦發現test
方法沒有使用,不但刪除test
,還會刪除"./something"
webpack 4 默認只能輸出 ES5 代碼
webpack 5 開始新增一個屬性 output.ecmaVersion, 能夠生成 ES5 和 ES6 / ES2015 代碼.
如:output.ecmaVersion: 2015
// webpack4
minSize: 30000;
複製代碼
// webpack5
minSize: {
javascript: 30000,
style: 50000,
}
複製代碼
// 配置緩存
cache: {
// 磁盤存儲
type: "filesystem",
buildDependencies: {
// 當配置修改時,緩存失效
config: [__filename]
}
}
複製代碼
緩存將存儲到 node_modules/.cache/webpack
以前 webpack 老是在第一次構建時輸出所有文件,可是監視從新構建時會只更新修改的文件。
這次更新在第一次構建時會找到輸出文件看是否有變化,從而決定要不要輸出所有文件。
entry: "./src/index.js
output.path: path.resolve(__dirname, "dist")
output.filename: "[name].js"
參考資料:
感謝尚硅谷視頻提供的視頻