摘要:一基礎(chǔ)配置項目安裝安裝并新建文件,并初始化文件入口出口配置插件安裝配置用來解析文件轉(zhuǎn)譯成瀏覽器可以識別的文件。以形式在頁面中插入代碼加載文件是否開啟代碼壓縮。
一.基礎(chǔ)配置 1.init項目
mkdir react-webpack-demo cd react-webpack-demo mkdir src mkdir dist npm init -y2.安裝webpack
安裝webpack,并新建webpack.js文件,并初始化文件
yarn add webpack webpack-cli webpack-dev-server -D mkdir config touch config/webpack.common.js
module.exports = { entry: ["./src/index.js"],//入口 output: { //出口 path: paths.appBuild }, module: {}, //配置 loader plugins: [], //插件 };3.安裝react react-dom
yarn add react react-dom4.配置loader
loaders
loader 用來解析文件轉(zhuǎn)譯成瀏覽器可以識別的文件。如.less、.jsx等這些文件瀏覽器是不能正常轉(zhuǎn)譯的,loaders的作用就是充當著"翻譯"的作用。
babel 輸入源碼 => 輸出編譯后的代碼,總共分為三個階段:解析,轉(zhuǎn)換,生成。
babel 本身不具有任何轉(zhuǎn)化功能,它把轉(zhuǎn)化的功能都分解到一個個 plugin 里面。因此當我們不配置任何插件時,經(jīng)過 babel 的代碼和輸入是相同的。
插件總共分為兩種:語法插件(Babel 解析(parse) 特定類型的語法,轉(zhuǎn)換插件會自動啟用語法插件),轉(zhuǎn)換插件(例如:箭頭函數(shù) (a) => a 就會轉(zhuǎn)化為 function (a) {return a})
預設(shè)(Presets)
preset 可以作為 Babel 插件的組合;
Preset 是逆序排列的(從后往前)
@babel/preset-react就是一個官方 Preset
@babel/polyfill
1.babel 默認只轉(zhuǎn)換 js 語法,而不轉(zhuǎn)換新的 API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(比如 Object.assign)都不會轉(zhuǎn)碼。
2.babel-polyfill 會污染全局變量,給很多類的原型鏈上都作了修改,如果我們開發(fā)的也是一個類庫供 其他開發(fā)者使用,這種情況就會變得非常不可控。
3.類庫開發(fā),通常我們會傾向于使用 babel-plugin-transform-runtime
4.@babel/preset-env 獲取您指定的任何目標環(huán)境,,按需轉(zhuǎn)碼,引入相應(yīng)的插件,默認使用browserslist
@babel/core-babel 核心模塊 @babel/preset-env 編譯ES6等 @babel/preset-react 轉(zhuǎn)換JSX @babel/preset-react 轉(zhuǎn)換JSX @babel/plugin-transform-runtime 避免 polyfill 污染全局變量,減小打包體積 @babel/polyfill ES6 內(nèi)置方法和函數(shù)轉(zhuǎn)化墊片
配置
{ test: /.(js|jsx)$/, include: paths.appSrc, use: [ { loader: "babel-loader", options: { presets: ["@babel/preset-react"], plugins: [ // 按需加載lodash "lodash", // babel-plugin-import // true是less, 可以寫"css" 如果不用less ["import", { libraryName: "antd", libraryDirectory: "es", style: "less" }], [ "@babel/plugin-transform-runtime", { absoluteRuntime: false, corejs: false, helpers: false, regenerator: true, // generator不會污染全局的 useESModules: false, // 轉(zhuǎn)換將使用無法運行的幫助程序 }, ], // "@babel/plugin-syntax-dynamic-import" ], cacheDirectory: true, cacheCompression: isEnvProduction, compact: isEnvProduction, }, }, ], }6. 按需引入Polyfill
Polyfill是一個js庫,主要撫平不同瀏覽器之間對js實現(xiàn)的差異。根據(jù)瀏覽器不同的UA按需加載polyfill,國內(nèi)瀏覽器支持不好。
style-loader :以形式在html頁面中插入css代碼
css-loader :加載.css文件 ,options{Minimize:是否開啟css代碼壓縮。modules:是否開啟css-modules}
postcss-loader :添加瀏覽器前綴
less-loader less轉(zhuǎn)css
可以通過匹配文件是否帶module分別配置是否要開始modules
const cssRegex = /.css$/; const cssModuleRegex = /.module.css$/;
module配置
modules: { mode: "local", localIdentName: "[local]--[hash:base64:5]", context: resolve(__dirname, "src"), hashPrefix: "my-less-hash", },8. 使用 source-map,對devtool進行優(yōu)化
devtool:"cheap-module-eval-source-map",// 開發(fā)環(huán)境配置
devtool:"cheap-module-source-map", // 線上生成配置
9. 使用 WebpackDevServerdevServer: { hot: true, contentBase: paths.appBuild, host: "0.0.0.0", // 可以使用手機訪問 port: 8080, historyApiFallback: true, // 該選項的作用所有的404都連接到index.html compress: true, inline: true, }二 優(yōu)化 1.文件路徑優(yōu)化
extension: 指定extension之后, 引入模塊的時候,可以不用擴展名
alias: 配置別名可以加快webpack查找模塊的速度
modules:去哪些目錄下尋找第三方模塊
resolve: { // 引入模塊的時候,可以不用擴展名 extensions: [".js", ".json", ".jsx"], // 別名 alias: { "@assets": resolve(__dirname, "../src/assets"), "@components": resolve(__dirname, "../src/components"), "@pages": resolve(__dirname, "../src/pages"), }, // 添加一個目錄到模塊搜索目錄 modules: [resolve(__dirname, "../src"), "node_modules"], },2.靜態(tài)資源托管到CDN時
filename:決定了每個輸出 bundle 的名稱
path:這些 bundle 將寫入到 output.path 選項指定的目錄下。
publicPath:將上面兩個準備的路徑字符串前面加上外部路徑,比如某個CDN:http://xx.xx.com/public/,此時原資源位置:js/xx.xxxxx.bundle.js --> http://xx.xx.com/public/js/xx...
3.MiniCssExtractPlugin ,抽取 css 文件css是直接打包進js里面的. 多帶帶生成css,css可以和js并行下載,提高頁面加載效率,
loader和plugins 都要配置
hash(所有文件哈希值相同,只要改變內(nèi)容跟之前的不一致,所有哈希值都改變,沒有做到緩存意義)
chunkhash(同一個模塊,就算將js和css分離,其哈希值也是相同的,修改一處,js和css哈希值都會變,同hash,沒有做到緩存意義)
contenthash(只要文件內(nèi)容不一樣,產(chǎn)生的哈希值就不一樣)
output和new MiniCssExtractPlugin() 時,配置 filename: "static/css/[name].[contenthash:8].css",
5. 代碼分割按需加載、提取公共代碼optimization
optimization: { minimize: isEnvProduction, // 找出模塊的順序,最小的初始包,product 默認開啟 occurrenceOrder: true, // runtimeChunk:會為每個僅含有 runtime 的入口起點添加一個額外 chunk; // 值 "single" 會創(chuàng)建一個在所有生成 chunk 之間共享的運行時文件。此設(shè)置是如下設(shè)置的別名: runtimeChunk: { name: "manifest" }, // usedExports 不導出未使用的代碼 usedExports: true, concatenateModules: true, splitChunks: { // chunks: "async", // 必須三選一: "initial" | "all"(推薦) | "async" (默認就是async) minSize: 30000, // 最小尺寸,默認值是30kb minChunks: 1, // 最小 chunk ,默認1 maxAsyncRequests: 5, // 最大異步請求數(shù), 默認5 maxInitialRequests: 3, // 最大初始化請求數(shù),默認3 automaticNameDelimiter: "-", // 打包分隔符 name: true, // 打包后的名稱,此選項可接收 function //設(shè)置緩存組,用來抽取滿足不同規(guī)則的chunk cacheGroups: { // 這里開始設(shè)置緩存的 chunks vendor: { // key 為entry中定義的 入口名稱 test: /[/]node_modules[/]/, // 正則規(guī)則驗證,如果符合就提取 chunk chunks: "initial", name: "vendor", // 要緩存的 分隔出來的 chunk 名稱 priority: 10, enforce: true, }, lazy: { test: ({ resource }) => { return /antd/.test(resource); }, chunks: "async", name: "lazy", priority: 10, enforce: true, }, commons: { chunks: "all", test: ({ resource }) => { return /[/]node_modules[/]/.test(resource) && !shouldExcludeFromCommon.test(resource); }, name: "common", minChunks: 2, maxInitialRequests: 5, minSize: 0, priority: 20, }, }, }, },6. 文件壓縮
webpack4只要在生產(chǎn)模式下, 代碼就會自動壓縮
7. 暴露全局變量new webpack.ProvidePlugin({ fetch: "imports-loader?this=>global!exports-loader?global.fetch!whatwg-fetch", }),8. 指定環(huán)境,定義環(huán)境變量
DefinePlugin 允許創(chuàng)建一個在編譯時可以配置的全局常量,這些值會被內(nèi)聯(lián)進那些允許傳一個代碼壓縮參數(shù)的代碼中,從而減少冗余的條件判斷
new webpack.DefinePlugin({ PRODUCTION: JSON.stringify(true), VERSION: JSON.stringify("5fa3b9"), BROWSER_SUPPORTS_HTML5: true, TWO: "1+1", "typeof window": JSON.stringify("object") })9. css tree sharking
npm i glob-all purify-css purifycss-webpack --save-dev const PurifyCSS = require("purifycss-webpack") const glob = require("glob-all") plugins:[ // 清除無用 css new PurifyCSS({ paths: glob.sync([ // 要做 CSS Tree Shaking 的路徑文件 path.resolve(__dirname, "./src/*.html"), // 請注意,我們同樣需要對 html 文件進行 tree shaking path.resolve(__dirname, "./src/*.js") ]) }) ]10. js Tree Shaking
清除到代碼中無用的js代碼,只支持import方式引入,不支持commonjs的方式引入
只要mode是production就會生效,develpoment的tree shaking是不生效的,因為webpack為了方便你的調(diào)試
optimization: {
usedExports:true,
}
10. 注意點rule配置順序影響構(gòu)建,無用的rule全部去掉。
loader 加載順序:從右向左:Webpack選擇了compose方式
11. 頁面緩存緩存一次后 服務(wù)器掛了 還可以用
// // 預緩存
new GenerateSW({
clientsClaim: true, skipWaiting: true, importWorkboxFrom: "local", include: [/.js$/, /.css$/, /.html$/, /.jpg/, /.jpeg/, /.svg/, /.webp/, /.png/],
}),
12. webpack-merge提取公共配置
module.exports = merge(common, webpackConfig);
MacBook Pro 2017上測試了幾把 ,并沒有提升速度,反而慢了,后續(xù)再看。
三 常見問題 1. antd 打包后icons dist文件很大resolve: {
alias: { "@ant-design/icons/lib/dist$": resolve(__dirname, "../src/assets/icons.js") },
}
并在icons.js 配置
按需引入antd配置:在babel-loader plugins中添加 如下配置
需要先安裝 babel-plugin-import
導入js和css模塊(LESS/Sass源文件): style: true
導入js和css模塊(css 內(nèi)置文件) style:"css"
["import", { libraryName: "antd", libraryDirectory: "es", style: true }],
如果是less 會報錯:需要在less-loader option 里面添加javascriptEnabled: true,
如果添加自定義主題: 添加 modifyVars:
{
"primary-color": "#1DA57A", "link-color": "#1DA57A", "border-radius-base": "2px",
},
3. antd 需要自行引入moment在index.html文件引入
4. css modulemodule: { rules: [ { test: /.css$/i, loader: "css-loader", options: { modules: { mode: "local", localIdentName: "[path][name]__[local]--[hash:base64:5]", context: path.resolve(__dirname, "src"), hashPrefix: "my-custom-hash", }, }, }, ], },5.UglifyjsWebpackPlugin不支持ES6語法
使用terser-webpack-plugin
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/105282.html
摘要:同時不能直接單純的指定輸出的文件名稱,比如,將會報錯,可以換成以下方式指定,或者其他類似方式。如果打包過程出現(xiàn)錯誤,比如語法錯誤,將會在控制臺以紅色文字顯示,并且在你修復之后會再次打包。 0x001 概述 其實我不知道怎么寫,所以決定就一塊一塊的寫點平常配置的過程,根據(jù)不同東西稍微分區(qū)一下就好了 0x002 初始化項目結(jié)構(gòu) $ mkdir webpack_study $ cd webp...
摘要:開始改建補充安裝依賴與上一次不同,這次我們基于進行改建,已經(jīng)有了很多依賴庫了,但我們?nèi)涡枰a充一個核心修改客戶端的配置修改文件,添加插件添加了這個配置以后,重新啟動項目通過地址就可以訪問到,頁面中出現(xiàn)的內(nèi)容就是所需要的。 從零開始搭建一個vue-ssr 前言 上次我們已經(jīng)實現(xiàn)了從零開始,搭建一個簡單的vue-ssr的demo:從零開始搭建一個vue-ssr(上)。那么這次呢,我們基于v...
摘要:從零開始搭建同構(gòu)應(yīng)用二項目工程化瀏覽器端在從零開始同構(gòu)開發(fā)一中我們已經(jīng)能實現(xiàn)基本的配置和編譯了。接下來我們需要將編譯工作工程化。配置作用自動生成自動在引入,。文件內(nèi)容如下同構(gòu)開發(fā)配置自動刷新這里我們用到的修飾器特性。 從零開始搭建React同構(gòu)應(yīng)用(二) 項目工程化(瀏覽器端) 在從零開始React同構(gòu)開發(fā)(一)中我們已經(jīng)能實現(xiàn)基本的React配置和編譯了。接下來我們需要將編譯工作工程...
摘要:概述上一章講的是,和這一章依舊沒有絲毫關(guān)系,這一章講的是和。插件介紹這個插件啊,用來預打包一些第三方庫,因為他們不經(jīng)常修改,而每次我們引用他們之后都要將他們不斷的打包一次又一次,不但浪費了調(diào)試編譯的時間,還浪費了時間。 0x001 概述 上一章講的是CommonChunkPlugin,和這一章依舊沒有絲毫關(guān)系,這一章講的是DllPlugin和DllReferencePlugin。 0x...
摘要:配置過程基本的入口出口配置入口輸出目錄這里使用方法是為了消除跨平臺的差異因為和的絕對路徑表示方式不一樣添加基本的加載器導入中加入對象使用的目標文件。 webpack配置過程 基本的入口出口配置 const webpack = require(webpack); const path = require(path); module.exports = { entry: { m...
摘要:插件介紹就是提供全局變量啦全局定義栗子初始化項目安裝依賴包編寫添加插件,并定義調(diào)用打包并用瀏覽器打開查看控制臺全局定義自定義函數(shù)栗子添加定義添加文件調(diào)用打包并執(zhí)行輸出資源源代碼 0x001 概述 上一章講的是definePlugin的用法,和這一章依舊沒有任何關(guān)系,這一章講的時候providerPlugin。 0x002 插件介紹 就是提供全局變量啦 0x003 全局定義jquery栗...
閱讀 2517·2021-11-25 09:43
閱讀 1275·2021-09-07 10:16
閱讀 2697·2021-08-20 09:38
閱讀 3001·2019-08-30 15:55
閱讀 1555·2019-08-30 13:21
閱讀 972·2019-08-29 15:37
閱讀 1503·2019-08-27 10:56
閱讀 2142·2019-08-26 13:45