摘要:構建構建就是把源代碼轉換成發布到線上的可執行代碼,包括如下內容。自動刷新監聽本地源代碼的變化,自動重新構建刷新瀏覽器。自動發布更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。將文件放入到項目中,在中新建一個放字體圖標的文件夾。
項目地址 github.com/wudiufo/Web…知識點概覽:
Loader,HMR ,Create React App, Caching, Plugin, SourceMap,Vue Cli 3.0 ,Shimming, WebpackDevServer,TreeShaking, CodeSplitting, Babel, React , Library, Eslint ,PWA, Vue, Mode,性能優化,多頁應用,原理, PreLoading, PreFetching ,環境變量,TypeScript
收獲:
一:初識Webpack徹底學會Webpack的配置 理解 Webpack的作用及原理 上手項目的打包過程配置 擁有工程化的前端思維 步入高級前端工程師行列
官網圖鎮樓:
1. 1 什么是WebPack
webpack 是一個現代 JavaScript 應用程序的靜態模塊打包工具:它做的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),并生成一個或多個 bundle,將其打包為合適的格式以供瀏覽器使用。
webpack構建:
構建就是把源代碼轉換成發布到線上的可執行 JavaScrip、CSS、HTML 代碼,包括如下內容。
1.代碼轉換:TypeScript 編譯成 JavaScript、SCSS或Less 編譯成 CSS 等。
2.文件優化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合并圖片等。
3.代碼分割:提取多個頁面的公共代碼、提取首屏不需要執行部分的代碼讓其異步加載。
4.模塊合并:在采用模塊化的項目里會有很多個模塊和文件,需要構建功能把模塊分類合并成一個文件。
5.自動刷新:監聽本地源代碼的變化,自動重新構建、刷新瀏覽器,nodemon。
6.代碼校驗:在代碼被提交到倉庫前需要校驗代碼是否符合規范,以及單元測試是否通過。
7.自動發布:更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。
構建其實是工程化、自動化思想在前端開發中的體現,把一系列流程用代碼去實現,讓代碼自動化地執行這一系列復雜的流程。 構建給前端開發注入了更大的活力,解放了我們的生產力,更加方便了我們的開發。
1.2 什么是 webpack 模塊
ES2015 import 語句
CommonJS require() 語句
AMD define 和 require 語句
css/sass/less 文件中的 @import 語句。
樣式(url(...))或 HTML 文件()中的圖片鏈接
詳細請看官網文檔:Modules MODULES
1.3 搭建Webpack環境
去官網下載node
// 查看node版本號 node -v // 查看npm版本號 npm -v1.4 初始化項目
mkdir webpack-productname
cd webpack-productname
//初始化webpack配置清單package.json
npm init -y
1.5 安裝webpack
//全局安裝(不推薦),因為如果有兩個項目用了webpack不同版本,就會出現版本不統一運行不起來的情況。只有卸了當前版本安裝對應版本非常麻煩。 npm install webpack webpack-cli -g //查看版本 webpack -v //全局卸載 npm uninstall webpack webpack-cli -g
//在項目里安裝webpack(推薦使用)。可以在不同項目中使用不同的webpack版本。
cd webpack-productname
npm install webpack webpack-cli -D
//查看版本
npx webpack -v
//查看對應包的詳細信息
npm info webpack
//安裝指定版本包
npm install webpack@4.16.1 webpack-cli -D
注意:
由于npm安裝走的是國外的網絡,比較慢容易出現安裝失敗的現象。
可以用yarn安裝,首先得全局安裝yarn,npm install yarn -g 。
或使用nrm快速切換npm源,首先得全局安裝nrm, npm install -g nrm。
nrm 使用:
nrm ls 查看可選源。
nrm test npm 測試速度。看哪個快就use哪個。
nrm use cnpm 使用cnpm 。
webpack-cli:使我們們可以在命令行里正確的使用webpack
1.6 webpack的配置文件webpack 開箱即用,可以無需使用任何配置文件。然而,webpack 會假定項目的入口起點為 src/index,然后會在 dist/main.js 輸出結果,并且在生產環境開啟壓縮和優化。通常,你的項目還需要繼續擴展此能力,為此你可以在項目根目錄下創建一個 webpack.config.js 文件,webpack 會自動使用它。
在項目根目錄下創建 webpack.config.js 文件,這是webpack默認配置文件
const path = require("path")
module.exports = {
//默認是production,打包的文件默認被壓縮。開發時可以設置為development,不被壓縮
mode:"production",
//打包項目的入口文件
entry: "./index.js",
//打包項目的輸出文件
output: {
//自定義打包輸出文件名
filename:"bundle.js",
//輸出文件的絕對路徑
path: path.resolve(__dirname,"bundle")
}
}
也可以自己指定配置文件來完成webpack的打包:
npx webpack --config + 自定義配置文件
詳細請看官方文檔:概念 配置
1.7 webpack打包輸出內容執行 `npm run build` 后,在控制臺輸出
Hash:1b245e275a547956bf52 //本次打包對應唯一一個hash值
Version:webpack 4.29.6 //本次打包對應webpack版本
Time:162ms Built at:2019-4-11 23:13:43 //本次打包耗時,及打包的時間
Asset Size Chunks Chunk Names //打包后的文件名,大小,id,入口文件名
bundle.js 1.36 KiB 0 [emitted] main
Entrypoint main=bundle.js
[0]./src/index.js 159 bytes {0}[built]
[1]./src/header.js 187 bytes {e}[built]
[2]./src/sidebar.js 193 bytes {e}[built]
[3]./src/content.js 193 bytes {e} [built]
二:Webpack核心概念
LOADER
2.1 什么是Loader
webpack可以使用 loader 來預處理文件,就是通過使用不同的Loader,webpack可以把不同的靜態文件都編譯成js文件,比如css,sass,less,ES6/7,vue,JSX等。
需要安裝 file-loader:解決CSS等文件中的引入圖片路徑問題
npm install file-loader -D
在 webpack.config.js 里添加 loader 配置
module.exports = {
//配置模塊,主要用來配置不同文件的加載器
module: {
//配置模塊規則
rules: [
{
test: /.(png|jpg|gif)$/, //正則匹配要使用相應loader的文件
use: [
{
loader: "file-loader", //要用到的loader
options: {
//palceholder占位符
name:"[name].[ext]", //打包后的圖片名字,后綴和打包的之前的圖片一樣
outputPath: "images/" //圖片打包后的地址
},
},
],
},
],
},
};
詳細請看官方文檔:file-loader
需要安裝 url-loader:當圖片小于limit的時候會把圖片BASE64編碼,大于limit參數的時候還是使用file-loader 進行拷貝
npm install url-loader -D
在 webpack.config.js 里添加 loader 配置
module.exports = {
module: {
rules: [
{
test: /.(png|jpg|gif|bmp/)$/i,
use: [
{
loader: "url-loader",
options: {
name:"[name].[ext]",
outputPath: "images/",
limit: 8192 //小于8192b,就可以轉化成base64格式。大于就會打包成文件格式
}
}
]
}
]
}
}
詳細請看官方文檔:url-loader
需要安裝 css-loader style-loader:
npm install css-loader style-loader -D
在 webpack.config.js 里添加 loader 配置
module.exports = {
module: {
rules: [
{
test: /.css$/, //匹配以css為后綴的文件
use: ["style-loader", "css-loader"],//loader的執行順序是從右向左,從下到上。css-loader:分析幾個css文件之間的關系,最終合并為一個css。style-loader:在得到css生成的內容時,把其掛載到html的head里,成為內聯樣式。
},
],
},
};
需要安裝 sass-loader node-sass:
npm install sass-loader node-sass -D
在 webpack.config.js 里添加 loader 配置
module.exports = {
...
module: {
rules: [{
test: /.scss$/,
use: [
"style-loader", // 將 JS 字符串生成為 style 節點
"css-loader", // 將 CSS 轉化成 CommonJS 模塊
"sass-loader" // 將 Sass 編譯成 CSS,默認使用 Node Sass
]
}]
}
};
為了瀏覽器的兼容性,有時候我們必須加入-webkit,-ms,-o,-moz這些前綴
Trident內核:主要代表為IE瀏覽器, 前綴為-ms
Gecko內核:主要代表為Firefox, 前綴為-moz
Presto內核:主要代表為Opera, 前綴為-o
Webkit內核:產要代表為Chrome和Safari, 前綴為-webkit
npm i postcss-loader autoprefixer -D
在項目跟目錄下創建 postcss.config.js
module.exports = {
plugins: [
require("autoprefixer")
]
}
webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /.scss$/,
use: [
"style-loader", // 將 JS 字符串生成為 style 節點
"css-loader", // 將 CSS 轉化成 CommonJS 模塊
"postcss-loader",//配置在css-loader后,在sass|less|stylus-loader 之前。
"sass-loader" // 將 Sass 編譯成 CSS,默認使用 Node Sass
]
}]
}
};
給loader加一些配置項:
webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options:{
importLoaders:2 ,//如果sass文件里還引入了另外一個sass文件,另一個文件還會從sass-loader向上解析。如果不加,就直接從css-loader開始解析。// 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
modules: true //開啟css的模塊打包。css樣式不會和其他模塊發生耦合和沖突
}
},
"postcss-loader",
"sass-loader",
]
}]
}
};
在 阿里巴巴矢量圖標庫中,把需要的字體圖標下載到本地,解壓。將iconfont.eot iconfont.svg iconfont.ttf iconfont.woff 文件放入到項目中,在src中新建一個放字體圖標的文件夾font。將iconfont.css文件拷貝到項目中,自己改一下引入字體圖標的路徑。
需要安裝 file-loader:
npm i file-loader -D
webpack.config.js
module.exports = {
...
module: {
rules: [{
test: /.(eot|ttf|svg|woff)$/,
use:{
loader:"file-loader"
}
},
]
}]
}
};
詳細請看官方文檔:asset-management
使用plugins讓打包更便捷
安裝:npm i html-webpack-plugin -D
基本用法:在 webpack.config.js 中:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
entry: "index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "index_bundle.js"
},
plugins: [new HtmlWebpackPlugin({
template: "src/index.html" //以index.html為模板,把打包生成的js自動引入到這個html文件中
})]
};
安裝:npm i clean-webpack-plugin -D
基本用法:在 webpack.config.js 中:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const path = require("path");
module.exports = {
entry: "index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "index_bundle.js"
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html" //在打包之后,以.html為模板,把打包生成的js自動引入到這個html文件中
}),
new CleanWebpackPlugin(["dist"]), // 在打包之前,可以刪除dist文件夾下的所有內容
]
};
在打包多入口文件時的配置
基本用法:在 webpack.config.js 中:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const path = require("path");
module.exports = {
entry: {
main: "./src/index.js",
sub: "./src/index.js"
},
output: {
publicPath: "http://cdn.com.cn", //將注入到html中的js文件前面加上地址
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html" //在打包之后,以.html為模板,把打包生成的js自動引入到這個html文件中
}),
new CleanWebpackPlugin(["dist"]), // 在打包之前,可以刪除dist文件夾下的所有內容
]
};
詳細請看官網:Output output-management
sourcemap:打包編譯后的文件和源文件的映射關系,用于開發者調試用。
source-map 把映射文件生成到多帶帶的文件,最完整但最慢
cheap-module-source-map 在一個多帶帶的文件中產生一個不帶列映射的Map
eval-source-map 使用eval打包源文件模塊,在同一個文件中生成完整sourcemap
cheap-module-eval-source-map sourcemap和打包后的JS同行顯示,沒有映射列
development環境推薦使用: devtool: "cheap-module-eval-source-map", production環境推薦使用: devtool: "cheap-module-source-map",
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "cheap-module-eval-source-map",
//devtool:"none",//在開發者模式下,默認開啟sourcemap,將其關閉
//devtool:"source-map"http://開啟映射打包會變慢
//devtool:"inline-source-map"http://不多帶帶生成.map文件,會將生成的映射文件以base64的形式插入到打包后的js文件的底部
//devtool:"cheap-inline-source-map"http://代碼出錯提示不用精確顯示第幾行的第幾個字符出錯,只顯示第幾行出錯,會提高一些性能
//devtool:"cheap-module-inline-source-map"http://不僅管自己的業務代碼出錯,也管第三方模塊和loader的一些報錯
//devtool:"eval"http://執行效率最快,性能最好,但是針對比較復雜的代碼的情況下,提示內容不全面
//devtool: "cheap-module-eval-source-map",//在開發環境推薦使用,提示比較全,打包速度比較快
//devtool: "cheap-module-source-map",//在生產環境中推薦使用,提示效果會好一些
entry: {
main: "./src/index.js"
},
module: {
rules: [{
test: /.(jpg|png|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
limit: 10240
}
}
}, {
test: /.(eot|ttf|svg)$/,
use: {
loader: "file-loader"
}
}, {
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader",
]
}]
},
plugins: [new HtmlWebpackPlugin({
template: "src/index.html"
}), new CleanWebpackPlugin(["dist"])],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
詳細請看官網:devtool
解決每次在src里編寫完代碼都需要手動重新運行 npm run dev
1.在 package.json 中配置
{ "name": "haiyang", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "bundle": "webpack", "watch": "webpack --watch",// 加--watch自動監聽代碼的變化 }, }
2.在 webpack.config.js 中,加 devServer
安裝 npm i webpack-dev-server –D
contentBase :配置開發服務運行時的文件根目錄
open :自動打開瀏覽器
host:開發服務器監聽的主機地址
compress :開發服務器是否啟動gzip等壓縮
port:開發服務器監聽的端口
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
module.exports = {
mode: "development",
devtool: "cheap-module-eval-source-map",
entry: {
main: "./src/index.js"
},
+ devServer: {
contentBase: "./dist",
open: true,
port: 8080,
proxy: {//配置跨域,訪問的域名會被代理到本地的3000端口
"/api": "http://localhost:3000"
}
},
module: {
rules: []
},
plugins: [],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
在 package.json 中:
{ "name": "haiyang", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "bundle": "webpack", "watch": "webpack --watch",// 加--watch自動監聽代碼的變化 "start": "webpack-dev-server",//配置熱更新 }, }
詳細請看官網 :dev-server
擴充知識:自己寫一個類似webpackdevserver的工具
了解即可,功能不全,自行擴展。
在 package.json 中:
{ "name": "haiyang", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "bundle": "webpack", "watch": "webpack --watch",// 加--watch自動監聽代碼的變化 "start": "webpack-dev-server",//配置熱更新 + "server" : "node server.js" //自己寫一個類似webpackdevserver的工具 }, }
安裝 :npm i express webpack-dev-middleware -D
在 項目根目錄下創建 server.js 文件
在 server.js 中
const express = require("express");
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const config = require("./webpack.config.js");
const complier = webpack(config);
const app = express();
app.use(webpackDevMiddleware(complier, {}));
app.listen(3000, () => {
console.log("server is running");
});
在 package.json 中:
{
"name": "haiyang",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server" //將文件打包到內存中,有助于開發
},
}
在 webpack.config.js 中
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
mode: "development",
devtool: "cheap-module-eval-source-map",
entry: {
main: "./src/index.js"
},
devServer: {
contentBase: "./dist",
open: true,
port: 8080,
+ hot: true,//開啟熱更新
+ hotOnly: true//盡管html功能沒有實現,也不讓瀏覽器刷新
},
module: {
rules: [{
test: /.(jpg|png|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
limit: 10240
}
}
}, {
test: /.(eot|ttf|svg)$/,
use: {
loader: "file-loader"
}
}, {
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader",
]
}, {
test: /.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new CleanWebpackPlugin(["dist"]),
+ new webpack.HotModuleReplacementPlugin() //使用模塊熱更新插件
],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
index.js
//如果模塊啟用了HMR,就可以用 module.hot.accept(),監聽模塊的更新。
if (module.hot) {
module.hot.accept("./library.js", function() {
// 使用更新過的 library 模塊執行某些操作...
})
}
注意點:
引入css,用框架Vue,React 時,不需要寫 module.hot.accept(),因為在使用css-loader,vue-loader,babel-preset時,就已經配置好了HMR,不需要自己寫
詳細請看官方文檔:hot-module-replacement api/hot-module-replacement concepts/hot-module-replacement
BABEL官網:babeljs.io/setup
安裝依賴包:
npm i babel-loader @babel/core @babel/preset-env -D //生產依賴,兼容低版本瀏覽器 npm install --save @babel/polyfill
在 webpack.config.js 中
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,//不需要對第三方模塊進行轉換,耗費性能
loader: "babel-loader" ,
options:{
"presets": [["@babel/preset-env",{
targets: {//這個項目運行在大于什么版本的瀏覽器上,已經支持es6的語法的高版本瀏覽器就不需要轉義成es5了
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns:"usage" //按需添加polyfill,把用到的代碼都轉成低版本瀏覽器兼容的
}]]
}
}
]
}
在 index.js 中:
//在業務代碼運行之前最頂部導入
import "@babel/polyfill";
注意:在開發類庫,第三方模塊或組件庫時不能用 @babel/polyfill 這種方案,因為會把聲明的變量變成全局變量,會污染全局環境。
安裝:
npm install --save-dev @babel/plugin-transform-runtime npm install --save @babel/runtime npm install --save @babel/runtime-corejs2
在 webpack.config.js 中
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,//不需要對第三方模塊進行轉換,耗費性能
loader: "babel-loader" ,
options:{
"plugins": [["@babel/plugin-transform-runtime",{
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}]]
}
}
]
}
由于babel需要配置的內容非常多,我們需要在項目根目錄下創建一個 .babelrc 文件。
就不需要在 webpack.config.js 中寫 babel 的配置了。
在 .babelrc 中:
{
"plugins": [["@babel/plugin-transform-runtime",{
"corejs": 2,
"helpers": true,
"regenerator": true,
"useESModules": false
}]]
}
業務代碼:
在 .babelrc 中:
{
"presets": [
["@babel/preset-env",{
targets: {
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1",
},
useBuiltIns:"usage"
}
],
"@babel/preset-react"
]
}
//執行順序:從下往上,從右向左的順序
安裝:
npm i react react-dom --save npm install --save-dev @babel/preset-react
詳細內容請看官網:babel-loader
在 webpack.config.js 中:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
mode: "development",
devtool: "cheap-module-eval-source-map",
entry: {
main: "./src/index.js"
},
devServer: {
contentBase: "./dist",
open: true,
port: 8080,
hot: true,
hotOnly: true
},
module: {
rules: []
},
plugins: [],
+ optimization: { //在開發環境中加,生產環境不加
usedExports: true
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
在 package.json 中:
{ + "sideEffects": ["*.css"], //對 所有的css文件 不使用Tree shaking。如果填 false,就是都需要用到Tree shaking }
詳細內容請看官網:tree-shaking
在項目根目錄下創建兩個文件,webpack.dev.js,webpack.prod.js
webpack.dev.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
mode: "development",
devtool: "cheap-module-eval-source-map",
entry: {
main: "./src/index.js"
},
devServer: {
contentBase: "./dist",
open: true,
port: 8080,
hot: true,
hotOnly: true
},
module: {
rules: [{
test: /.js$/,
exclude: /node_modules/,
loader: "babel-loader",
}, {
test: /.(jpg|png|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
limit: 10240
}
}
}, {
test: /.(eot|ttf|svg)$/,
use: {
loader: "file-loader"
}
}, {
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader",
]
}, {
test: /.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new CleanWebpackPlugin(["dist"]),
new webpack.HotModuleReplacementPlugin()
],
optimization: {
usedExports: true
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
webpack.prod.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
mode: "production",
devtool: "cheap-module-source-map",
entry: {
main: "./src/index.js"
},
module: {
rules: [{
test: /.js$/,
exclude: /node_modules/,
loader: "babel-loader",
}, {
test: /.(jpg|png|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
limit: 10240
}
}
}, {
test: /.(eot|ttf|svg)$/,
use: {
loader: "file-loader"
}
}, {
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader",
]
}, {
test: /.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new CleanWebpackPlugin(["dist"]),
],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "dist")
}
}
在 package.json 中:
{
"scripts": {
"dev": "webpack-dev-server --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
},
}
解決 webpack.dev.js,webpack.prod.js 存在大量重復代碼,在項目根目錄下創建一個 webpack.common.js 文件,把公共代碼提取出來
安裝 :
npm i webpack-merge -D
webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
module.exports = {
entry: {
main: "./src/index.js"
},
module: {
rules: [{
test: /.js$/,
exclude: /node_modules/,
loader: "babel-loader",
}, {
test: /.(jpg|png|gif)$/,
use: {
loader: "url-loader",
options: {
name: "[name]_[hash].[ext]",
outputPath: "images/",
limit: 10240
}
}
}, {
test: /.(eot|ttf|svg)$/,
use: {
loader: "file-loader"
}
}, {
test: /.scss$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
importLoaders: 2
}
},
"postcss-loader",
"sass-loader",
]
}, {
test: /.css$/,
use: [
"style-loader",
"css-loader",
"postcss-loader"
]
}]
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html"
}),
new CleanWebpackPlugin(["dist"],{
root:path.resolve(__dirname,"../")
}),
],
output: {
filename: "[name].js",
path: path.resolve(__dirname, "../dist")
}
}
webpack.dev.js
const webpack = require("webpack");
const merge = require("webpack-merge")
const commenConfig = require("./webpack.commin.js")
const devConfig = {
mode: "development",
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: "./dist",
open: true,
port: 8080,
hot: true,
hotOnly: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
optimization: {
usedExports: true
},
}
//將開發配置和公共配置做結合
module.exports = merge(commenConfig, devConfig)
webpack.prod.js
const merge = require("webpack-merge")
const commenConfig = require("./webpack.commin.js")
const prodConfig = {
mode: "production",
devtool: "cheap-module-source-map",
}
//將線上配置和公共配置做結合
module.exports = merge(commenConfig, prodConfig)
最后在根目錄下創建一個build文件夾,將 webpack.common.js , webpack.dev.js ,webpack.prod.js 放在build文件夾下,統一管理。
在 package.json 中:
{
"scripts": {
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js"
},
}
詳細請看官網文檔:guides/production
安裝: npm i lodash --save npm i babel-plugin-dynamic-import-webpack -D
代碼分割,和webpack無關,為了提升性能 webpack中實現代碼分割,兩種方式:
第一種方法:同步代碼: 只需要在webpack.common.js中做optimization的配置即可
第二種方法:異步代碼(import): 異步代碼,無需做任何配置,會自動進行代碼分割,放置到新的文件中
第一種方法:在 webpack.common.js 中
module.exports = {
entry: {
main: "./src/index.js"
},
module: {
rules: []
},
plugins: [],
+ optimization:{
+ splitChunks:{ //啟動代碼分割,有默認配置項
+ chunks:"all"
+ }
+ },
output: {}
}
第二種方法在 .babelrc 中:
{
presets: [
[
"@babel/preset-env", {
targets: {
chrome: "67",
},
useBuiltIns: "usage"
}
],
"@babel/preset-react"
],
+ plugins: ["dynamic-import-webpack"]
}
詳細內容請看官網:code-splitting
安裝:npm install --save-dev @babeL/plugin-syntax-dynamic-import
在業務 index.js 中:
function getComponent() {
return import(/* webpackChunkName:"lodash" */ "lodash").then(({ default: _ }) => {
var element = document.createElement("div");
element.innerHTML = _.join(["1", "2"], "-");
return element;
})
}
getComponent().then(element => {
document.body.appendChild(element);
});
在 .babelrc 中:
{
presets: [
[
"@babel/preset-env", {
targets: {
chrome: "67",
},
useBuiltIns: "usage"
}
],
"@babel/preset-react"
],
+ plugins: ["@babeL/plugin-syntax-dynamic-import"]
}
在 webpack.common.js 中:
module.exports = {
entry: {
main: "./src/index.js"
},
module: {
rules: []
},
plugins: [],
+ optimization:{
+ splitChunks:{ //啟動代碼分割,不寫有默認配置項
+ chunks: "all",//參數all/initial/async,只對所有/同步/異步進行代碼分割
minSize: 30000, //大于30kb才會對代碼分割
maxSize: 0,
minChunks: 1,//打包生成的文件,當一個模塊至少用多少次時才會進行代碼分割
maxAsyncRequests: 5,//同時加載的模塊數最多是5個
maxInitialRequests: 3<
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7340.html
摘要:前言本文基于,主要涉及基本概念基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行優化配置。同一文件中,修改某個影響其他。 前言:本文基于weboack4.x,主要涉及webpack4 基本概念、基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行...
摘要:別踩白塊兒使用白鷺引擎編寫的游戲游戲地址準備工作了解白鷺引擎并安裝編寫工具安裝游戲引擎安裝創建項目創建項目可以選擇不同版本的引擎,創建成功之后還可以查看,對發布進行設置。 別踩白塊兒 使用(白鷺引擎)Egret編寫的游戲 showImg(https://user-gold-cdn.xitu.io/2018/10/26/166af8033a59fdbf?w=500&h=840&f=gif...
摘要:詳細具體的使用可以見文章手摸手,帶你優雅的使用。為了加速線上鏡像構建的速度,我們利用源進行加速并且將一些常見的依賴打入了基礎鏡像,避免每次都需要重新下載。 完整項目地址:vue-element-admin系類文章二:手摸手,帶你用vue擼后臺 系列二(登錄權限篇)系類文章三:手摸手,帶你用vue擼后臺 系列三(實戰篇)系類文章四:手摸手,帶你用vue擼后臺 系列四(vueAdmin 一...
摘要:社區的認可目前已經是相關最多的開源項目了,體現出了社區對其的認可。監聽事件手動維護列表這樣我們就簡單的完成了拖拽排序。 完整項目地址:vue-element-admin 系類文章一:手摸手,帶你用vue擼后臺 系列一(基礎篇)系類文章二:手摸手,帶你用vue擼后臺 系列二(登錄權限篇)系類文章三:手摸手,帶你用vue擼后臺 系列三(實戰篇)系類文章四:手摸手,帶你用vue擼后臺 系列...
摘要:社區的認可目前已經是相關最多的開源項目了,體現出了社區對其的認可。監聽事件手動維護列表這樣我們就簡單的完成了拖拽排序。 完整項目地址:vue-element-admin 系類文章一:手摸手,帶你用vue擼后臺 系列一(基礎篇)系類文章二:手摸手,帶你用vue擼后臺 系列二(登錄權限篇)系類文章三:手摸手,帶你用vue擼后臺 系列三(實戰篇)系類文章四:手摸手,帶你用vue擼后臺 系列...
閱讀 2487·2021-08-11 11:16
閱讀 2926·2019-08-30 15:55
閱讀 3332·2019-08-30 12:53
閱讀 1568·2019-08-29 13:28
閱讀 3263·2019-08-28 18:17
閱讀 935·2019-08-26 12:19
閱讀 2466·2019-08-23 18:27
閱讀 695·2019-08-23 18:17