重學webpack4之基礎篇

2021-03-02 前端早讀課

前言

重學Webpack4專題來了,本文有一種代碼片段的既視感。本專題有字節跳動@xfz投稿分享。

@xfz,字節跳動高級前端開發,負責ToB業務的設計、研發與維護,夢想做一名幼師

正文從這開始~~

安裝基礎

依賴入口

// 單入口,SPA

entry: 'xx/xx.js'

// 多入口 MPA

entry: {

app: './src/app.js',

adminApp: './src/adminApp.js'

}

output

指定打包後的輸出

output: {

path: path.resoluve(__diranme,'dist')

filename: '[name].js' // 單入口可以寫死文件名,多入口一定要使用佔位符[name],來自動生成多個文件

// filename: '[name].[chunkhash:5]]js'

// filename: '[name].[hash]js'

}

Loaders

wepback開箱即用只支持JS和JSON兩種文件類型,通過Loader去支持其他文件類型並把他們轉化成有效的模塊,並且可以添加到依賴圖中

本身是一個函數,接受源文件作為參數,返迴轉換的結果

例如: babel/ts-loader、css/less/scss-loader、url/file-loader、raw-loader(將.txt文件以字符串的形式導入)、thread-loader(多進程打包js和css)

module: {

rules: [

{test: /.txt$/, use: 'raw-loader'},

{test: /.css$/, use: [

{

loader: 'css-loader',

options: {

modules: {

localIdentName: '[path][name]__[local]--[hash:base64:5]'

}

}

}

]}

]

}

解析ES6

使用babel-loader,babel的配置文件.babelrc

安裝 babel-loader、@babel/core @babel/preset-env

// webpack.config

module: {

rules: [

{test: /.js?x$/, use: 'babel-loader', exclude: /node_modules/}

]

}

// .babelrc

{

"presets": [

"@babel/preset-env",

"@babel/preset-react"

],

"plugins": [

// 各種插件

"@babel/propsoal-class-properties"

]

}

css/less/scss-loader

css-loader用於加載.css文件,並且轉換成 common 對象

style-loader 將樣式通過 style 標籤,插入到 head 中

// use: [loader1,loader2,loader3],loader的處理順序是 3>2>1,從後往前

module: {

rules: [

{

test: /.s?css$/,

use: [

isDev ? 'style-loader' : MiniCssExtractPlugin.loader

{

loader: 'css-loader',

options: {

importLoaders: 1,

// css模塊化使用

modules: {

localIdentName: '[path][name]__[local]--[hash:base64:5]'

}

}

},

'postcss-loader',

'sass-loader'

],

include: [],

exclude: [

Root('src/components')

]

},

]

}

url/file-loader

用於處理文件,圖片、字體、多媒體

url-loader 實現較小的圖片轉成base64,插入到代碼中,當超過限制的limit後,會自動降級到file-loader

{

test: /\.(png|jpg|jpeg|gif|eot|woff|woff2|ttf|svg|otf)$/,

use: [

{

loader: 'url-loader',

options: {

limit: 10 * 1024, // 10k

name: isDev ? 'images/[name].[ext]' : 'images/[name].[hash.[ext]',

publicPath: idDev ? '/' : 'cdn地址',

},

},

// prduction,用於圖片壓縮

{

loader: 'image-webpack-loader',

options: {

bypassOnDebug: true

}

}

]

},

postcss-loader

預處理器, autoprefixer(需要安裝)

rules: [

{test: /.css$/, use: [

{

'style-loader',

'css-loader',

{

loader: 'postcss-loader',

options: {

plugins: () => {

require('autoprefixer')({

browsers: ['last 2 version', '>1%', 'ios7']

})

}

}

},

'sass-loader'

}

]

}

或者將postcss-loader的options放在根目錄的postcss.config.js中

rules: [

{

test: /.css$/,

use: [

'style-loader',

'css-loader',

'postcss-loader'

'less-loader',

]

}

]

// postcss.config.js 和 package.json(或者.browserslistrc,推薦使用.browserslistrc)

// 安裝postcss-preset-env,autoprefixer

module.exports = {

loader: 'postcss-loader',

plugins: {

'postcss-preset-env': {

stage: 0,

features: {

'nesting-rules': true,

'autoprefixer': { grid: true },

''

}

}

}

};

// package.json

"browserslist": [

"last 2 version",

">1%",

"iOS >= 7"

]

// .browserslistrc

last 2 version

>1%

iOS >= 7

px自動轉rem(兩種方式)

方式一:px2rem-loader與lib-flexible,頁面渲染時計算根元素的font-size,推薦使用:

cnpm i -D px2rem-loader

cnpm i -S lib-flexible

不推薦,將lib-flexible代碼拷貝到 html>head>script中使用raw-loader內聯lib-flexible

rules: [

{

test: /.css$/,

use: [

{

'style-loader',

'css-loader',

'postcss-loader',

{

loader: 'px2rem-loader',

options: {

remUnit: 75, // 一個rem等於多少px

remPrecision: 8 // px轉換成rem的小數位

}

}

'sass-loader',

}

]

}

方式二,使用postcss-loader與postcss-px2rem-exclude

module.exports = {

loader: 'postcss-loader',

plugins: {

'postcss-preset-env': {

stage: 0,

features: {

'nesting-rules': true,

'autoprefixer': { grid: true },

}

},

'postcss-px2rem-exclude': {

remUnit: 200,

exclude: /node_modules/i

}

}

};

plugins

插件用於bundle文件的優化,資源管理和環境變量注入,作用於整個構建過程

plugins: [

new HtmlWpeckPlugin({})

]

webpack-dev-server

webpack-dev-server,開啟本地伺服器,監聽文件變化後,熱更新頁面

不刷新瀏覽器而是熱更新,不輸出文件,而是放在內存中

配合 new.webpack.HotModuleReplacementPlugin() 或 react-hot-loader 插件使用

// package.json

webpack-dev-server mode=development -open

// config

module.exports = {

devServer: {

host: '0.0.0.0',

compress: true,

port: '3000',

contentBase: join(__dirname, '../dist'),//監聽的目錄,用於刷新瀏覽器

hot: true,

overlay: {

errors: true,

warnings: true

},

disableHostCheck: true,

publicPath: '/', // 設置時,要與output.publicPath保持一致

historyApiFallback: true,

// historyApiFallback: {

// rewrites: [from: /.*/, to: path.posix.join('/', // 'index.html')],

//}

proxy: {

'/api': 'http://localhost:8081',

}

//proxy: {

// '/api/*': {

// target: 'https://xxx.com',

// changeOrigin: true,

// secure: false,

// headers: {},

// onProxyReq: function(proxyReq, req, res) {

// proxyReq.setHeader('origin', 'xxx.com');

// proxyReq.setHeader('referer', 'xxx.com');

// proxyReq.setHeader('cookie', 'xxxxx');

// },

// onProxyRes: function(proxyRes, req, res) {

// const cookies = proxyRes.header['set-cookie'];

// cookies && buildCookie(cookies)

// }

// }

// }

},

}

webpack-dev-middleware

將webpack輸出文件傳輸給伺服器,適用於靈活的定製場景

const express = requrie('express')

const webpack = require('webpack')

const webpackDevMiddleware = requrie('webpack-dev-middleware')

const app = express()

const config = require('./webpack.config.js')

const compiler = webpack(config)

app.use(webpackDevMiddleware(compiler, {

publicPath: config.output.publicPath

}))

app.listen(3000)

熱更新原理

mini-css-extract-plugin和optimize-css-assets-webpack-plugin

提取css,建議使用contenthash

module: {

rules: [

{

test: /.s?css$/,

use: [

isDev ? 'style-loader' : iniCssExtractPlugin.loader

{

loader: 'css-loader',

options: {

importLoaders: 1,

// css模塊化使用

modules: {

localIdentName: '[path][name]__[local]--[hash:base64:5]'

}

}

},

'postcss-loader',

'sass-loader'

]

},

]

},

plugins: [

// 提取css

new MiniCssExtractPlugin({

filename: 'styles/[name].[contenthash:5].css',

}),

// 壓縮css

new OptimizeCSSAssetsPlugin({

assetNameRegExp: /\.css$/g,

cssProcessor: require("cssnano"),//需要安裝cssnano

cssProcessorPluginOptions: {

preset: [

'default',

{

discardComments: {

removeAll: true

}

}

]

},

canPrint: true

}),

]

html-webpack-plugin

plugins: [

new HtmlWebpackPlugin({

// 自定義參數title傳遞到html中

// html中使用<title><%= htmlWebpackPlugin.options.title %></title>

// <script>let number = <%= htmlWebpackPlugin.options.number %><script>

number: 1,

title: '京程一燈CRM系統',

filename: 'index.html',

// chunks: ['index'] //用於多頁面,使用哪些chunk

template: resolve(__dirname, '/src/index.html'),

minify: {

minifyJS: true,

minifyCSS: true,

removeComments: true,

collapseWhitespace: true,

preserveLineBreak: false,

removeAttributeQuotes: true,

removeComments: false

}

}),

]

clean-webpack-plugin 或者使用 rimraf dist

plugins: [

new CleanWebpackPlugin()

]

mode

Mode 用來指定當前構建環境 development、production 和 none

設置 mode 可以使用 wepack內置函數,內部自動開啟一些配置項,默認值為 production

內置功能

development:process.env.NODE_ENV為development,開啟NamedChunksPlugin 和 NameModulesPlugin

這兩個插件用於熱更新,控制臺列印路徑

prodution:process.env.NODE_ENV為prodution.開啟 FlagDependencyUsagePlugin、ModuleConcatenationPlugin、NoEmitOnErrorsPlugin,OccurrentceOrderPlugin、SideEffectsFlagPlugin等

none:不開啟任何優化選項

watch

文件監聽可以在webpack命令後加上 --watch 參數,或在webpack.config中設置watch:true原理:輪詢判斷文件的最後編輯時間是否變化

module.exports = {

// 默認false,不開啟

watch: true,

// 只有開啟時,watchOptions才有意義

watchOptions: {

// 忽略,支持正則

ignored: /node_modules/,

// 監聽到變化後等300ms再執行,默認300ms

aggregateTimeout: 300,

// 怕亂文件是否變化是通過不停詢問系統指定文件有沒變化實現的,默認每秒1000次

poll: 1000

}

}

文件指紋

打包後輸出文件名後綴,也就是hash值

hash:和整個項目構建相關,只要項目中有一個文件修改,整個項目中的文件hash都會修改成統一的一個

chunkhash:和webpck打包的chunk有關,不同的entry會生成不同的chunkhash值(適用於js文件)

contenthash:根據文件內容定義hash,文件內容不變,則contenthash不變,用於批量更新(適用於css文件)

資源內聯

頁面框架的初始化,比如flexible

上報相關打點

css內聯避免頁面閃動

代碼:

// raw-loader@0.5.1 內聯html片段,在template中弄

<!-- 內聯html -->

<%= require('raw-loader!./meta.html') %>

// raw-loader內聯js

<!-- 初始化腳本,例如flexible -->

<script><%= require('raw-loader!babel-loader!../node_modules/lib-flexible/flexible.js') %></script>

css內聯合

方式一:style-loader

module: {

rules: [

{

test: /.s?css$/,

use: [

{

loader: 'style-loader',

options: {

injectType: 'singletonStyleTag', // 將所有style標籤合併成一個

}

}

'css-loader'

'postcss-loader',

'sass-loader'

]

},

]

},

方式二:html-inline-css-webpack-plugin

首先使用 mini-css-extract-plugin(而非 style-loader)將 css 提取打包成一個獨立的 css chunk 文件。然後使用 html-webpack-plugin 生成 html 頁面。最後使用 html-inline-css-webpack-plugin 讀取打包好的 css chunk 內容注入到頁面,原本 html-webpack-plugin 只會引入 css 資源地址,現在實現了 css 內聯

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const HtmlWebpackPlugin = require('html-webpack-plugin');

const HTMLInlineCSSWebpackPlugin = require("html-inline-css-webpack-plugin").default;

module.exports = {

module: {

rules: [

{

test: /\.css$/,

use: [

MiniCssExtractPlugin.loader,

"css-loader"

]

}

]

},

plugins: [

new MiniCssExtractPlugin({

filename: "[name].css",

chunkFilename: "[id].css"

}),

new HtmlWebpackPlugin(),

new HTMLInlineCSSWebpackPlugin(),

],

}

style-loader vs html-inline-css-webpack-plugin

請求成面:減少HTTP網絡請求數

多頁面應用 MPA

解決方案:

// 例如 ./src/index/index.js 與 ./src/search/index.js

// path: './src/*/index.js'

const setMPA = filenames => {

const entry = {}, htmlWebpackPlugins = [];

const entryFiles = glob.sync(path.join(__dirname, filenames))

for(let item of entryFiles){

// (/\/([a-z\_\$]+)\/index.js$/)

const match = item.match(/src\(.*)/index\.js$/)

const pageName = match && match[1];

entry[pageName] = item

htmlWebpackPlugins.push(

new HtmlWebpackPlugin({

template: `src/${pageName}/index.html`,

filename: `${pageName}.html`,

chunks: ["runtime", "common", pageName],

minify: {

// ..

}

})

)

}

return {

entry,

htmlWebpackPlugins

}

}

entry: entry

plugin: [//].concat(htmlWebpackPlugins)

source-map

開發環境:建議使用

首先在原始碼的列信息是沒有意義的,只要有行信息就能完整的建立打包前後代碼之間的依賴關係。因此不管是開發環境還是生產環境,我們都會選擇增加cheap基本類型來忽略模塊打包前後的列信息關聯。

其次,不管在生產環境還是開發環境,我們都需要定位debug到最最原始的資源,比如定位錯誤到jsx,coffeeScript的原始代碼處,而不是編譯成js的代碼處,因此,不能忽略module屬性

再次我們希望通過生成.map文件的形式,因此要增加source-map屬性

module.expors = {

// 開發,因為eval的rebuild速度快,因此我們可以在本地環境中增加eval屬性

devtool: 'cheap-module-eval-source-map'

// 生產

devtool: 'cheap-module-source-map'

}

代碼拆分基礎庫分離

將react、react-dom基礎包通過cdn引入,不打入到bundle中

方式一: externals

// 1

module.exports = {

externals: {

react: 'React',

'react-dom': 'ReactDOM',

'react-router-dom': 'ReactRouterDOM',

mobx: 'mobx'

},

}

2. 在html模版中 script標籤引入對應的cdn地址

方式二:html-webpack-externals-plugin(推薦使用)

1.在html模版中 script標籤引入對應的cdn地址

2.plugins: [

new HtmlWebpackPlugin(),

new htmlWebpackExternalsPlugin({

externals: [

{

module: 'react',

entry: react的cdn地址,

global: 'React'

},

{

module: 'react-dom',

entry: react-dom的cdn地址,

global: 'ReactDOM'

},

{

module: 'react-router-dom',

entry: react-router-dom的cdn地址,

global: 'ReactRouterDOM'

},

// ...

]

})

]

方式三:webpack4 替代 CommonsChunckPlugin插件

module.exports = {

optimization: {

minimize: true,

runtimeChunk: {

name: 'manifest'

},

splitChunks: {

chunks: 'async', // async異步引入庫進行分離(默認),initial同步引入庫分離,all所有引入庫分離

minSize: 30000, // 抽離公共包最小的大小

maxSize: 0,

minChunks: 1, // 最小使用的次數

maxAsyncRequests: 5,

maxInitialRequests: 3,

name: true,

cacheGroups: {

// 提取基礎庫,不使用CDN的方式

//commons: {

// test: /(react|react-dom|react-router-dom)/,

// name: "vendors",

// chunks: 'all'

//},

// 提取公共js

commons: {

chunks: "all", // initial

minChunks: 2,

maxInitialRequests: 5,

minSize: 0,

name: "commons"

},

// vendors: {

// test: /[\\/]node_modules[\\/]/,

// priority: -10

// }

// 合併所有css

// styles: {

// name: 'style',

// test: /\.(css|scss)$/,

// chunks: 'all',

// minChunks: 1,

// enforce: true

// }

}

}

},

}

tree-shaking(靜態分析,不是動態分析)

原理:利用ES6模塊的特點:

代碼擦除: uglify階段刪除無用代碼

Scope Hoisting

代碼:

(function(module, __webpack_exports__,__webpack_require__){

__webpack_require__.r(__webpack_exports__);

})()

開啟scop hoisting

代碼分割

splitChunck

動態引用

適用場景:抽離相同代碼到一個共享塊

腳本懶加載,使得初始下載代碼更小

懶加載JS腳本方式

// 配置.babelrc

"plugins": [

["@babel/plugin-syntax-dynamic-import"],

]

dist代碼通過window['webpackJsonp']來獲取對應腳本

ESlint

//.eslint.js

/ 區分生產環境、開發環境

const _mode = process.env.NODE_ENV || 'production';

module.exports = {

"env": {

"browser": true,

"es6": true,

"node": true,

},

"globals": {

"$": true,

"process": true,

"dirname": true,

},

"parser": "babel-eslint",

"extends": "eslint:recommended",

"parserOptions": {

"ecmaFeatures": {

"jsx": true,

"legacyDecorators": true

},

"ecmaVersion": 2018,

"sourceType": "module"

},

"plugins": [

"react"

],

"rules": {

"no-console": "off",

"no-debugger": _mode==='development' ? 0 : 2,

"no-alert": _mode==='development' ? 0 : 2,

// "no-multi-spaces": "error",

"no-unused-vars": "off", // react中不適用

"no-constant-condition": "off",

"no-fallthrough": "off",

// "keyword-spacing": ["error", { "before": true} ], // 不生效,先注釋

// "indent": [

// "error",

// 2

// ],

"linebreak-style": [

"error",

"unix"

],

// "quotes": [

// "error",

// "single"

// ],

"semi": [0],

"no-unexpected-multiline": 0,

"no-class-assign": 0,

}

};

檢查eslint

方式一: 安裝husky,增加npm script,適合老項目

"scripts": {

//"precommit": "eslint --ext .js --ext .jsx src/",

"precommit": "eslint lint-staged", // 增量檢查修改的文件

},

"lint-staged": {

//"src/**/*.js": [

// "eslint --ext .js --ext .jsx",

// "git add"

//]

"linters": {

"*.[js,scss]": ["eslint --fix", "git add"]

}

}

方式二:webpack與eslint結合,新項目

rules: [

{

test: /\.jsx?$/,

exclude: /node_modules/,

use: ['babel-loader', 'eslint-loader']

}

]

其實新項目中,可以將兩種方式同時使用

優化命令行日誌

統計信息 stats,webpack屬性,這種方式不好

error-only:值發生錯誤時輸出

minimal:只在發生錯誤或有新的編譯時輸出

none:沒有輸出

normal:標準輸出,默認

verbose:全部輸出

// development

devServer: {

//

stats: 'errors-only'

}

// production

module.exports = {

stats: 'errors-only'

}

stats結合friendly-errors-webpack-plugin(推薦)

plugins: [

new FriendlyErrorsPlugin()

],

stats: 'errors-only'

構建異常和中斷處理

wepback4之前的版本構建失敗不會跑出錯誤碼

node中的process.exit規範

主動捕獲錯誤,並處理構建錯誤

代碼如下:

plugins: [

function() {

// webpack3 this.plugin('done', (stats) => {})

// webpack4

this.hooks.done.tap('done', (stats) => {

if (stats.compilation.errors && stats.compilation.errors.length && process.argv.indexOf('--watch') == -1) {

console.log('build error');

// dosomething

process.exit(1);

}

})

}

]

關於本文作者:@xfz原文:https://juejin.im/post/6893511215768272909

本專題其他文章

重學webpack4之原理分析

相關焦點

  • 看完 Webpack 源碼,我學到了這些
    這,把正在寫此篇文章的我也問住了。理提綱時,認為 WHY 最好寫,幾句話就可帶過,但事實證明真要較真這一塊還值得一說。擅自揣測下會閱讀 Webpack 源碼夥伴可能的動機:作者最先是原因是 4,然後是 1,2。當然,1,2 應該是大多數人看項目源碼的動機。搭建源碼調試環境要閱讀源碼,首先拿到源碼,然後最後能邊調試邊閱讀。
  • Webpack打包全世界
    const HtmlWebpackPlugin = require('html-webpack-plugin'); //通過 npm 安裝const webpack = require('webpack'); //訪問內置的插件const path = require('path');const config = { entry: '.
  • 前端必備技能 webpack - 4. webpack處理CSS資源
    Stylus 文件;PostCSS 和 Stylus:[1] PostCSS 官網地址:https://www.postcss.com.cn/[2] Stylus 官網地址:https://stylus.bootcss.com/這裡推薦張鑫旭大大提供翻譯的 Stylus 中文文檔:[3] 張鑫旭 · Stylus 中文版參考文檔之綜述
  • 【webpack】webpack 中最易混淆的 5 個知識點
    前兩天為了優化公司的代碼打包項目,惡補了很多 webpack4 的知識。要是放在幾年前讓我學習 webpack 我肯定是拒絕的,之前看過 webpack 的舊文檔,比我們內部項目的文檔還要簡陋。但是最近看了一下 webpack4 的文檔,發現 webpack官網的 指南[1] 寫的還不錯,跟著這份指南學會 webpack4 基礎配置完全不是問題,想系統學習 webpack 的朋友可以看一下。
  • webpack4.x 系列-entry(入口)
    之前寫過webpack4系列文章,本次對webpack4進行更再次研究學習webpack官網webpck中文網中文網更新慢
  • 【Webpack】654- 了不起的 Webpack Scope Hoisting 學習指南
    _0__util_js__ = __webpack_require__(1);    console.log(__WEBPACK_IMPORTED_MODULE_0__util_js__["a"]);  }),  (function (module, __webpack_exports__, __webpack_require__) {    __webpack_exports
  • Webpack 多入口配置,看這篇,足夠了
    本文字數:8539字預計閱讀時間:21分鐘建議閱讀方式:收藏備用溫馨提示:最近全國大幅降溫,注意防寒保暖,開心跨年長按識別,後臺回復 「電子書」 即可領取《JavaScript高級程序設計(第準備工作首先我們 vue init webpack multi-entry-vue 使用 vue-cli 創建一個 webpack 模版的項。文件結構如下:.
  • webpack4 處理頁面
    圖文編輯:開三金前言:1.plugins 是webpack4的插件集合,可以用一些插件擴展webpack4 的功能,就比如HtmlWebpackPlugin2.HtmlWebpackPlugin的主要作用是:為html文件中引入的外部資源如script
  • Webpack vs Rollup
    2017年4月份的時候,Facebook將React的構建工具換成了Rollup。很多人就有疑問了,Webpack不也是Facebook團隊開發的嗎,為什麼不使用它而是要換成第三方構建工具呢?先別急,等你看完這篇文章,你就知道為什麼了。一、Webpack誕生於2012年,目前Javascript社區使用得比較多的構建工具。
  • webpack教程:如何從頭開始設置 webpack 5
    webpack 對我來說曾經是一個怪物般存在一樣,因為它有太多太多的配置項,相反,使用像create-react-app腳手架可以很輕鬆創建項目,所以有一段時間內,我會儘量避免使用 webpack,因為它看起來既複雜又望而卻步 😊如果你們不習慣從頭開始設置 webpack
  • Webpack 3 從入門到放棄
    前言如果你用過 webpack 且一直用的是 webpack 1,請參考 從v1遷移到v2 (v2 和 v3 差異不大) 對版本變更的內容進行適當的了解,然後再選擇性地閱讀本文。首先,這篇文章是根據當前最新的 webpack 版本 (即 v3.4.1) 撰寫,較長一段時間內無需擔心過時的問題。
  • 圖解Webpack——實現Plugin
    Plugin是webpack生態系統的重要組成部分,其目的是解決loader無法實現的其他事,可用於執行範圍更廣的任務,為webpack帶來很大的靈活性。目前存在的plugin並不能完全滿足所有的開發需求,所以定製化符合自己需求的plugin成為學習webpack的必經之路。下面將逐步闡述plugin開發中幾個關鍵技術點並實現plugin。
  • webpack基本配置有哪些?如何搭建webpack?
    主要內容webpack學習目標第一節 webpack介紹1.webpack介紹webpack 是一個模塊打包器。webpack 的主要目標是將 JavaScript 文件打包在一起,打包後的文件用於在瀏覽器中使用,但它也能夠勝任轉換(transform)、打包(bundle)。
  • Webpack的使用指南-Webpack的常用解決方案
    1.自動構建HTML,可壓縮空格,可給引用的js加版本號或隨機數:html-webpack-plugin解決方案:使用插件 html-webpack-pluginwebpack.config.js如下:module.exports = {entry: '.
  • webpack簡單介紹
    4) 配置package.json文件{"name": "app","version": "1.0.0","description": "","main">"dev":"webpack .path:path.resolve(__dirname,'dist'),//相對地址轉絕對地址filename:'build.js'}3) entry是配置入口文件(可以寫成JSON形式配置多個入口),output為出口配置4)
  • 擼一個webpack插件!!
    而將這些插件控制在webapck事件流上的運行的就是webpack自己寫的基礎類Tapable。Tapable暴露出掛載plugin的方法,使我們能將插件控制在webapack事件流上運行(如下圖)。後面我們將看到核心的對象 Compiler,Compilation等都是繼承於Tabable類。Tabable是什麼?
  • 從Webpack打包後的文件分析導入的原理
    主流框架中,不論是 React 還是 Vue,都是使用 Webpack 進行資源的打包,這篇文章我們試著分析打包後的 bundle 文件來了解下其是如何進行靜態和動態導入的。/src/a.js":    function (module, __webpack_exports__, __webpack_require__) {    "use strict";    __webpack_require__.r(__webpack_exports__);    const asyncText = "async";    __webpack_exports
  • 18款Webpack插件,總會有你想要的!
    來源 | https://github.com/Michael-lzg/my--article/blob/master/webpack/這篇文章整理了
  • Webpack命令字典大全
    全局進行安裝webpack(熟手不建議)$ npm install webpack -g查看wepback版本信息 相當有用$ npm info webpack卸載wepback>$ npm uninstall webpack安裝指定版本 #=小老鼠$ npm install webpack#1.31.x --save-dev下載webpack插件到node_modules 並在package.json文件中加上webpack的配置內容
  • webpack系列---loader
    webpack本身只能打包Javascript文件,對於其他資源例如 css,圖片,或者其他的語法集比如jsx,是沒有辦法加載的。 這就需要對應的loader將資源轉化,加載進來。所謂 loader 只是一個導出為函數的 JavaScript 模塊。