亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

webpack4.0 入門實踐教程

2019-11-19 12:46:48
字體:
來源:轉載
供稿:網友

webpack 可以看做是模塊打包機:他做的事情是,分析你的項目結構,找到 JavaScript 模塊以及其他的一些瀏覽器不能直接運行的擴展語言( Scss 、 TypeScript 等),將其打包為合適的格式以供瀏覽器使用

構建就是把源代碼轉換成發布到線上可執行的 JavaScript 、CSS、HTML 代碼,包括以下內容:

  • 代碼轉換TypeScript 編譯成 JavaScript 、 SCSS 編譯成 CSS 等等 文件優化 :壓縮 JavaScript 、CSS、HTML 代碼,壓縮合并圖片等
  • 代碼分割 :提取多個頁面的公共代碼、提取首屏不需要執行部分的代碼讓其異步加載
  • 模塊合并 :在采用模塊化的項目有很多模塊和文件,需要構建功能把模塊分類合并成一個文件
  • 自動刷新 :監聽本地源代碼的變化,自動構建,刷新瀏覽器
  • 代碼校驗 :在代碼被提交到倉庫前需要檢測代碼是否符合規范,以及單元測試是否通過
  • 自動發布 :更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。

構建其實是工程化、自動化思想在前端開發中的體現。把一系列流程用代碼去實現,讓代碼自動化地執行這一系列復雜的流程。

webpack 的基本概念

入口(entry point): 指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始,webpack 會找出有哪些模塊和 library 是入口起點(直接和間接)依賴的。

默認值是 ./src/index.js ,然而,可以通過在 webpack 配置中配置 entry 屬性,來指定一個不同的入口起點(或者也可以指定多個入口起點)。

出口 output: 屬性告訴 webpack 在哪里輸出它所創建的 bundles,以及如何命名這些文件,主輸出文件默認為 ./dist/main.js ,其他生成文件的默認輸出目錄是 ./dist

loader: 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉換為 webpack 能夠處理的有效模塊,然后你就可以利用 webpack 的打包能力,對它們進行處理。

注意,loader 能夠 import 導入任何類型的模塊(例如 .css 文件),這是 webpack 特有的功能,其他打包程序或任務執行器的可能并不支持。我們認為這種語言擴展是有很必要的,因為這可以使開發人員創建出更準確的依賴關系圖。

插件 plugins: loader 被用于轉換某些類型的模塊,而插件則可以用于執行范圍更廣的任務。插件的范圍包括,從打包優化和壓縮,一直到重新定義環境中的變量。插件接口功能極其強大,可以用來處理各種各樣的任務。

模式 mode: 通過選擇 developmentproduction 之中的一個,來設置 mode 參數,你可以啟用相應模式下的 webpack 內置的優化

webpack 構建過程

  • 從 Entry 里配置的 Module 開始遞歸解析 Entry 依賴的所有 Module。
  • 每找到一個 Module, 就會根據配置的 Loader 去找出對應的轉換規則。
  • 對 Module 進行轉換后,再解析出當前 Module 依賴的 Module。
  • 這些模塊會以 Entry 為單位進行分組,一個 Entry 和其所有依賴的 Module 被分到一個組也就是一個 Chunk。
  • 最后 Webpack 會把所有 Chunk 轉換成文件輸出。
  • 在整個流程中 Webpack 會在恰當的時機執行 Plugin 里定義的邏輯。

開發環境和生產環境

我們在日常的前端開發工作中,一般都會有兩套構建環境:一套開發時使用,一套供線上使用。

  • development : 用于開發的配置文件,用于定義 webpack dev server 和其他東西
  • production : 用于生產的配置文件,用于定義 UglifyJSPluginsourcemaps

簡單來說,開發時可能需要打印 debug 信息,包含 sourcemap 文件,而生產環境是用于線上的即代碼都是壓縮后,運行時不打印 debug 信息等。譬如 axios、antd 等我們的生產環境中需要使用到那么我們應該安裝該依賴在生產環境中,而 webpack-dev-server 則是需要安裝在開發環境中

平時我們 npm 中安裝的文件中有 -S -D, -D 表示我們的依賴是安裝在開發環境的,而-S 的是安裝依賴在生產環境中。

本文就來帶你搭建基本的前端開發環境,前端開發環境需要什么呢?

  • 構建發布需要的 HTML、CSS、JS、圖片等資源
  • 使用 CSS 預處理器,這里使用 less
  • 配置 babel 轉碼器 => 使用 es6+
  • 處理和壓縮圖片
  • 配置熱加載,HMR

以上配置就可以滿足前端開發中需要的基本配置。下面是本文打包后的效果圖:

 

搭建基本的開發環境

安裝

mkdir webpack-dev && cd webpack-devnpm init -ynpm i webpack webpack-cli -D

添加 scripts

生成了 package.json 文件,在文件中添加

 "scripts": { "build": "webpack --mode production" }

-- mode 模式 (必選,不然會有 WARNING ),是 webpack4 新增的參數選項,默認是 production

--mode production 生產環境

  • 提供 uglifyjs-webpack-plugin 代碼壓縮
  • 不需要定義 new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") })
  • 默認 production 默認開啟 NoEmitOnErrorsPlugin -> optimization.noEmitOnErrors , 編譯出錯時跳過輸出,以確保輸出資源不包含錯誤
  • 默認開啟 ModuleConcatenationPlugin -> optimization.concatenateModules , webpack3 添加的作用域提升( Scope Hoisting )

--mode development 開發環境

  • 使用 eval 構建 module, 提升增量構建速度
  • 不需要定義 new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }) 默認 development
  • 默認開啟 NamedModulesPlugin -> optimization.namedModules 使用模塊熱替換(HMR)時會顯示模塊的相對路徑

添加了 scripts 之后,新建 src/index.js ,然后執行 npm run build ,你就會發現新增了一個 dist 目錄,里邊存放的是 webpack 構建好的 main.js 文件。

ps npm scripts 使用指南

新建 webpack.config.js 文件

要想對 webpack 中增加更多的配置信息,我們需要建立一個 webpack 的配置文件。在根目錄下創建 webpack.config.js 后再執行 webpack 命令,webpack 就會使用這個配置文件的配置了

配置中具備以下的基本信息:

module.exports = { entry: '', // 打包入口:指示 webpack 應該使用哪個模塊,來作為構建其內部依賴圖的開始 output: '', // 出口 resolve: {}, // 配置解析:配置別名、extensions 自動解析確定的擴展等等 devServer: {}, // 開發服務器:run dev/start 的配置,如端口、proxy等 module: {}, // 模塊配置:配置loader(處理非 JavaScript 文件,比如 less、sass、jsx、圖片等等)等 plugins: [] // 插件的配置:打包優化、資源管理和注入環境變量}

配置打包入口和出口

首先我們往 webpack.config.js 添加點配置信息

const path = require('path')module.exports = { // 指定打包入口 entry: './src/index.js', // 打包出口 output: { path: path.resolve(__dirname, 'dist'), // 解析路徑為 ./dist filename: 'bundle.js' }}

上面我們定義了打包入口 ./src/index.js ,打包出口為 ./dist , 打包的文件夾名字為 bundle.js ,執行 npm run build 命令后,index.js 文件會被打包為 bundle.js 文件。此時隨便建立一個 html 文件引用這個 bundle.js 就可以看到你在 index.js 寫的代碼了。

path.resolve([...paths]) 方法會把一個路徑或路徑片段的序列解析為一個絕對路徑。

使用 html-webpack-plugin 創建 html 文件

更多情況下我們不希望打包一次,就新建一次 html 文件來引用打包后的文件,這樣顯得不智能或者說當你打包的文件名修改后,引用路徑就會出錯。

這個時候我們就可以使用html-webpack-plugin 插件來將 HTML 引用路徑和我們的構建結果關聯起來。

npm install html-webpack-plugin -D

創建文件 public/index.html 修改 webpack.config.js 文件

const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { //... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 配置輸出文件名和路徑 template: './public/index.html' // 配置要被編譯的html文件 }) ]}

重新執行 npm run build , dist 目錄就會多個 index.html 并引入了 bundle.js .

壓縮 html 文件

修改 webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = { //... plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 配置輸出文件名和路徑 template: './public/index.html', // 配置要被編譯的html文件 hash: true, // 壓縮 => production 模式使用 minify: { removeAttributeQuotes: true, //刪除雙引號 collapseWhitespace: true //折疊 html 為一行 } }) ]}

打包 css 文件

我們希望使用 webpack 來進行構建 css 文件,,為此,需要在配置中引入 loader 來解析和處理 CSS 文件:

npm install style-loader css-loader -D

新建 src/assets/style/color.css , 修改 webpack.config.js 文件:

module.exports = { //... module: { /** * test: 匹配特定條件。一般是提供一個正則表達式或正則表達式的數組 * include: 匹配特定條件。一般是提供一個字符串或者字符串數組 * exclude: 排除特定條件 * and: 必須匹配數組中的所有條件 * or: 匹配數組中任何一個條件, * nor: 必須排除這個條件 */ rules: [ { test: //.css$/, include: [path.resolve(__dirname, 'src')], use: ['style-loader', 'css-loader'] } ] } //...}

經由上述兩個 loader 的處理后,CSS 代碼會轉變為 JS, 如果需要單獨把 CSS 文件分離出來,我們需要使用 mini-css-extract-plugin 插件

抽取 css 到獨立文件, 自動添加前綴

npm i mini-css-extract-plugin postcss-loader autoprefixer -D

我們在寫 css 時不免要考慮到瀏覽器兼容問題,如 transform 屬性,需要添加瀏覽器前綴以適配其他瀏覽器。故使用到 postcss-loader 這個 loader, 下面則是相關的配置

webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = { // ... module: { rules: [ { test: //.css$/, include: [path.resolve(__dirname, 'src')], use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] } } ] } ] }, plugins: [ //... new MiniCssExtractPlugin({ filename: '[name].css', chunkFilename: '[id].css' }) ]}

打包 less 文件

開發中通常會用到一門預處理語言,這里以 less 為例,通過 less-loader 可以打包 less 為 css 文件

npm install less less-loader -D

新建 src/assets/style/index.less , 并且在 src/index.js 中引入 import './assets/style/index.less'

配置 webpack.config.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')module.exports = { module: { rules: [ // ... { test: //.less$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] // 添加css中的瀏覽器前綴 } }, 'less-loader' ] } ] } //...}

執打包命令后就可以發現 index.less 中寫的樣式會和 color.css 一樣被打包進 main.css 中。

webpack@v4 升級踩坑: 關于使用 mini-css-extract-plugin 的注意點。

打包圖片

npm install file-loader url-loader -D

file-loader:可以用于處理很多類型的文件,它的主要作用是直接輸出文件,把構建后的文件路徑返回。

url-loader:如果圖片較多,會發很多 http 請求,會降低頁面性能。 url-loader 會將引入的圖片編碼,生成 dataURl。相當于把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只需要引入這個文件就能訪問圖片了。當然,如果圖片較大,編碼會消耗性能。因此 url-loader 提供了一個 limit 參數,小于 limit 字節的文件會被轉為 DataURl,大于 limit 的還會使用 file-loader 進行 copy。

  • url-loader 可以看作是增強版的 file-loader。
  • url-loader 把圖片編碼成 base64 格式寫進頁面,從而減少服務器請求。
module.exports = { module: { rules: [ // ... { test: //.(png|jpg|gif)$/, use: [ { loader: 'url-loader', options: { outputPath: 'images/', //輸出到images文件夾 limit: 500 //是把小于500B的文件打成Base64的格式,寫入JS } } ] } ] } //...}

url-loader 和 file-loader 是什么關系呢?

簡單地說, url-loader 封裝了 file-loaderurl-loader 不依賴于 file-loader ,即使用 url-loader 時,只需要安裝 url-loader 即可,不需要安裝 file-loader ,因為 url-loader 內置了 file-loader 。

通過上面的介紹,我們可以看到,url-loader 工作分兩種情況:

  • 文件大小小于 limit 參數,url-loader 將會把文件轉為 DataURL;
  • 文件大小大于 limit,url-loader 會調用 file-loader 進行處理,參數也會直接傳給 file-loader。因此我們只需要安裝 url-loader 即可。

有關 url-loaderfile-loader 的解析:webpack 之圖片引入-增強的 file-loader:url-loader

配置 babel

babel-loader

Babel 是一個讓我們能夠使用 ES 新特性的 JS 編譯工具,我們可以在 webpack 中配置 Babel,以便使用 ES6、ES7 標準來編寫 JS 代碼。

Babel 7 的相關依賴包需要加上 @babel scope。一個主要變化是 presets 設置由原來的 env 換成了 @babel/preset-env , 可以配置 targets , useBuiltIns 等選項用于編譯出兼容目標環境的代碼。其中 useBuiltIns 如果設為 "usage" ,Babel 會根據實際代碼中使用的 ES6/ES7 代碼,以及與你指定的 targets,按需引入對應的 polyfill ,而無需在代碼中直接引入 import '@babel/polyfill' ,避免輸出的包過大,同時又可以放心使用各種新語法特性。

npm i babel-loader @babel/core @babel/preset-env -D

筆者這里配的版本號如下

{ "babel-loader": "^8.0.4", "@babel/core": "^7.1.2", "@babel/preset-env": "^7.1.0"}

babel-loader: 用 babel 轉換 ES6 代碼需要使用到 babel-loader

@babel-preset-env: 默認情況下是等于 ES2015 + ES2016 + ES2017,也就是說它對這三個版本的 ES 語法進行轉化。

 @babel/core:babel 核心庫

根目錄下新建 .babelrc 文件

{ "presets": [ [ "@babel/preset-env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] }, "useBuiltIns": "usage" } ] ]}
  • presets 是一堆 plugins 的預設,起到方便的作用。
  • plugins 是編碼轉化工具,babel 會根據你配置的插件對代碼進行相應的轉化。

修改 webpack.config.js

module.exports = { module: { rules: [ //... { test: //.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader' } } ] }}

babel/polyfill 和 transform-runtime

Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API ,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局對象,以及一些定義在全局對象上的方法(比如 Object.assign)都不會轉碼。

babel-polyfill: 如上述所說,對于新的 API,你可能需要引入 babel-polyfill 來進行兼容

關鍵點

  • babel-polyfill 是為了模擬一個完整的 ES2015+環境,旨在用于應用程序而不是庫/工具。
  • babel-polyfill 會污染全局作用域

babel-runtime 的作用:

  • 提取輔助函數 。ES6 轉碼時,babel 會需要一些輔助函數,例如 _extend。babel 默認會將這些輔助函數內聯到每一個 js 文件里, babel 提供了 transform-runtime 來將這些輔助函數“搬”到一個單獨的模塊 babel-runtime 中,這樣做能減小項目文件的大小。
  • 提供 polyfill :不會污染全局作用域,但是不支持實例方法如 Array.includes

babel-runtime 更像是分散的 polyfill 模塊,需要在各自的模塊里單獨引入,借助 transform-runtime 插件來自動化處理這一切,也就是說你不要在文件開頭 import 相關的 polyfill ,你只需使用, transform-runtime 會幫你引入。

對于開發應用來說,直接使用上述的按需 polyfill 方案是比較方便的,但如果是開發工具、庫的話,這種方案未必適合( babel-polyfill 是通過向全局對象和內置對象的 prototype 上添加方法實現的,會造成全局變量污染)。Babel 提供了另外一種方案 transform-runtime ,它在編譯過程中只是將需要 polyfill 的代碼引入了一個指向 core-js 中對應模塊的鏈接(alias)。關于這兩個方案的具體差異和選擇,可以自行搜索相關教程,這里不再展開,下面提供一個 transform-runtime 的參考配置方案。

首先安裝 runtime 相關依賴

npm i @babel/plugin-transform-runtime -Dnpm i @babel/runtime -S

修改 .babelrc

{ //... "plugins": ["@babel/plugin-transform-runtime"]}

打包前清理源目錄文件 clean-webpack-plugin

每次打包,都會生成項目的靜態資源,隨著某些文件的增刪,我們的 dist 目錄下可能產生一些不再使用的靜態資源,webpack 并不會自動判斷哪些是需要的資源,為了不讓這些舊文件也部署到生產環境上占用空間,所以在 webpack 打包前最好能清理 dist 目錄。

npm install clean-webpack-plugin -D

修改 webpack.config.js 文件

const CleanWebpackPlugin = require('clean-webpack-plugin')module.exports = { plugins: [new CleanWebpackPlugin(['dist'])]}

提取公用代碼

假如你 a.jsb.js 都 import 了 c.js 文件,這段代碼就冗雜了。為什么要提取公共代碼,簡單來說,就是減少代碼冗余,提高加載速度。

module.exports = { //... optimization: { splitChunks: { cacheGroups: { commons: { // 抽離自己寫的公共代碼 chunks: 'initial', name: 'common', // 打包后的文件名,任意命名 minChunks: 2, //最小引用2次 minSize: 0 // 只要超出0字節就生成一個新包 }, styles: { name: 'styles', // 抽離公用樣式 test: //.css$/, chunks: 'all', minChunks: 2, enforce: true }, vendor: { // 抽離第三方插件 test: /node_modules/, // 指定是node_modules下的第三方包 chunks: 'initial', name: 'vendor', // 打包后的文件名,任意命名 // 設置優先級,防止和自定義的公共代碼提取時被覆蓋,不進行打包 priority: 10 } } } }}

hash

hash 是干嘛用的? 我們每次打包出來的結果可能都是同一個文件,那我上線的時候是不是要替換掉上線的 js,那我怎么知道哪是最新的呢,我們一般會清一下緩存。而 hash 就是為了解決這個問題而存在的

我們此時在改一些 webpack.config.js 的配置

module.exports = { //... output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[hash:8].js' }, //... plugins: [ new MiniCssExtractPlugin({ filename: '[name].[hash:8].css', chunkFilename: '[id].[hash:8].css' }) ]}

減少 resolve 的解析,配置別名

如果我們可以精簡 resolve 配置,讓 webpack 在查詢模塊路徑時盡可能快速地定位到需要的模塊,不做額外的查詢工作,那么 webpack 的構建速度也會快一些

module.exports = { resolve: { /** * alias: 別名的配置 * * extensions: 自動解析確定的擴展, * 比如 import 'xxx/theme.css' 可以在extensions 中添加 '.css', 引入方式則為 import 'xxx/theme' * @default ['.wasm', '.mjs', '.js', '.json'] * * modules 告訴 webpack 解析模塊時應該搜索的目錄 * 如果你想要添加一個目錄到模塊搜索目錄,此目錄優先于 node_modules/ 搜索 * 這樣配置在某種程度上可以簡化模塊的查找,提升構建速度 @default node_modules 優先 */ alias: { '@': path.resolve(__dirname, 'src'), tool$: path.resolve(__dirname, 'src/utils/tool.js') // 給定對象的鍵后的末尾添加 $,以表示精準匹配 }, extensions: ['.wasm', '.mjs', '.js', '.json', '.jsx'], modules: [path.resolve(__dirname, 'src'), 'node_modules'] }}

webpack-dev-serve

上面講到了都是如何打包文件,但是開發中我們需要一個本地服務,這時我們可以使用 webpack-dev-server 在本地開啟一個簡單的靜態服務來進行開發。

webpack-dev-server 是 webpack 官方提供的一個工具,可以基于當前的 webpack 構建配置快速啟動一個靜態服務。當 modedevelopment 時,會具備 hot reload 的功能,即當源碼文件變化時,會即時更新當前頁面,以便你看到最新的效果。...

npm install webpack-dev-server -D

package.json 中 scripts 中添加

"start": "webpack-dev-server --mode development"

默認開啟一個本地服務的窗口 http://localhost:8080/ 便于開發

配置開發服務器

我們可以對 webpack-dev-server 做針對性的配置

module.exports = { // 配置開發服務器 devServer: { port: 1234, open: true, // 自動打開瀏覽器 compress: true // 服務器壓縮 //... proxy、hot }}
  • contentBase: 服務器訪問的根目錄(可用于訪問靜態資源)
  • port: 端口
  • open: 自動打開瀏覽器

 模塊熱替換(hot module replacement)

模塊熱替換( HMR - Hot Module Replacement )功能會在應用程序運行過程中替換、添加或刪除模塊,而無需重新加載整個頁面。主要是通過以下幾種方式,來顯著加快開發速度:

  • 保留在完全重新加載頁面時丟失的應用程序狀態。
  • 只更新變更內容,以節省寶貴的開發時間。
  • 調整樣式更加快速 - 幾乎相當于在瀏覽器調試器中更改樣式。

上面我們 npm start 后修改一次文件,頁面就會刷新一次。這樣就存在很大問題了,比如我們使用 redux , vuex 等插件,頁面一刷新那么存放在 redux , vuex 中的東西就會丟失,非常不利于我們的開發。

HMR 配合 webpack-dev-server ,首先我們配置下 webpack.config.js

const webpack = require('webpack')module.exports = { devServer: { //... hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() //... ]}

配置后還不行,因為 webpack 還不知道你要更新哪里, 修改 src/index.js 文件, 添加

if (module.hot) { module.hot.accept()}

重啟服務, npm start 之后,修改引入 index.js 文件后,頁面就不會重新刷新了,這便實現了 HMR

但是但是有個問題是,你修改 css/less 等樣式文件并未發生改變, what ?

HMR 修改樣式表 需要借助于 style-loader , 而我們之前用的是 MiniCssExtractPlugin.loader , 這也好辦,修改其中一個 rules 就可以了,我們可以試試改

module.exports = { module: { rules: [ { test: //.less$/, use: [ // MiniCssExtractPlugin.loader, 'style-loader', 'css-loader', { loader: 'postcss-loader', options: { plugins: [require('autoprefixer')] // 添加css中的瀏覽器前綴 } }, 'less-loader' ] } ] }}

這樣我們修改 less 文件就會發現 HMR 已經實現了。

其實,我們可以發現,dev 下配置的 loader 為 style-loader , 而生產環境下則是需要 MiniCssExtractPlugin.loader

這就涉及到了不同環境之間的配置??梢酝ㄟ^ process.env.NODE_ENV 獲取當前是開發環境或者是生產環境,然后配置不同的 loader,這里就不做展開了。下一篇文章打算在做一個 react-cli 或者 vue-cli 的配置,將開發環境的配置與生產環境的配置分開為不同的文件。

結語

前面講到的知識都是 webpack 的一些基礎的知識,更多的資料可以查詢webpack 中文官網,官網講的比較詳細,我這里也是講最常的配置,也是一篇入門系列的文章,文中涉及的知識點還有很多地方還需要完善,譬如 優化 webpack 的構建速度, 減小打包的體積等等。

學習 webpack 4.0 還需要多實踐,多瞎搞,筆者也是剛剛學習 webpack 的配置,不對之處請各位指出。

下一篇文章打算從零配置一個腳手架,以加深自己對 webpack 的理解。

本文產生的代碼: webpack-dev

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品久久久久久久久久久| 欧美区在线播放| 国产精品视频久久久久| 日韩亚洲欧美中文高清在线| 日韩精品电影网| 国产在线999| 日韩亚洲国产中文字幕| 欧美精品成人91久久久久久久| 一区三区二区视频| 亚洲精品国产精品国自产观看浪潮| 国产视频福利一区| 91综合免费在线| 久久婷婷国产麻豆91天堂| 久久综合色影院| 色999日韩欧美国产| 97精品伊人久久久大香线蕉| 97成人精品区在线播放| 欧美日韩国产精品一区二区不卡中文| 亚洲另类激情图| 日韩欧美国产激情| 国产区精品视频| 国产精品成人免费视频| 26uuu日韩精品一区二区| 久久亚洲精品网站| 国产精品日韩欧美大师| 国产日韩一区在线| 亚洲成人在线网| 国产成+人+综合+亚洲欧美丁香花| 91人人爽人人爽人人精88v| 色哟哟网站入口亚洲精品| 亚洲美女精品久久| 久久99精品久久久久久琪琪| 国产精品视频免费观看www| 日本久久精品视频| 精品久久香蕉国产线看观看亚洲| 亚洲综合在线小说| 国产ts一区二区| 久久成人精品电影| 久久99久国产精品黄毛片入口| 欧美日韩亚洲一区二区| 国产精品久久久久久久app| 另类美女黄大片| 国产精品久久久久久久7电影| 日韩视频免费大全中文字幕| 91欧美激情另类亚洲| 日韩中文字幕亚洲| 精品亚洲一区二区三区四区五区| 色综合久久天天综线观看| 久久视频在线观看免费| 国产成人精品免高潮在线观看| 国产成人在线一区| 91精品国产成人| 亚洲国产欧美一区二区三区同亚洲| 欧美日韩在线另类| 国产美女精彩久久| 91伊人影院在线播放| 国产精品成久久久久三级| 亚洲精品一区二区三区婷婷月| 亚洲一区制服诱惑| 伊人青青综合网站| 国产精品自产拍高潮在线观看| 97视频在线免费观看| 国模吧一区二区| 亚洲免费视频一区二区| 欧洲成人午夜免费大片| 欧美一区第一页| 国产经典一区二区| 91精品久久久久久综合乱菊| 午夜精品一区二区三区av| 欧美激情videos| 久久久999国产精品| 中文字幕日韩欧美在线视频| 91在线免费观看网站| www.国产一区| 亚洲欧美日韩久久久久久| 亚洲成成品网站| 日本精品视频在线| 欧美一区二三区| 久久男人av资源网站| 久久精视频免费在线久久完整在线看| zzjj国产精品一区二区| 日本三级韩国三级久久| 久久国产精品电影| 亚洲成人久久久| 久久久综合免费视频| 97视频在线观看视频免费视频| 欧美精品aaa| 日韩在线视频网站| 欧美裸体xxxx极品少妇软件| 国产精品视频午夜| 久久99久国产精品黄毛片入口| 成人免费高清完整版在线观看| 亚洲精品视频中文字幕| 欧美成人精品一区| 成人午夜一级二级三级| 亚洲欧美第一页| 久久人91精品久久久久久不卡| 麻豆国产精品va在线观看不卡| 亚洲欧洲黄色网| 国产精品欧美日韩| 国产成人一区二区三区| 欧美日韩国产色| 成人xxxx视频| 欧美日韩激情美女| 精品久久久久久久久久久久久久| 国产成人亚洲综合| 性欧美在线看片a免费观看| 国产视频精品免费播放| 一本色道久久综合狠狠躁篇的优点| 欧美洲成人男女午夜视频| 欧美久久精品午夜青青大伊人| 日韩视频在线观看免费| 国产精品视频一区二区高潮| 国产精品香蕉国产| 欧美日本国产在线| 伊人久久久久久久久久久| 日韩av一卡二卡| 日韩在线观看免费| 国产精品自产拍在线观| 久久精品成人一区二区三区| 精品国内自产拍在线观看| 欧美激情喷水视频| 欧美另类xxx| 中文字幕视频一区二区在线有码| 91精品国产91久久久久久吃药| 欧美一区二区三区四区在线| 欧美猛男性生活免费| 美女久久久久久久久久久| 免费不卡在线观看av| 国产精品综合网站| 日韩中文有码在线视频| 91最新国产视频| 国产一区二区在线播放| 欧美老女人www| 亚洲欧美日韩一区二区在线| 中国日韩欧美久久久久久久久| 亚洲天堂第二页| 中文字幕亚洲无线码在线一区| 亚洲最大的成人网| 中文字幕日本精品| 中文字幕欧美日韩精品| 亚洲欧美日韩一区二区在线| 91精品久久久久| 国产精品久久久久久久久影视| 日韩精品视频在线播放| 久久久国产精彩视频美女艺术照福利| 97精品国产91久久久久久| 日本精品久久中文字幕佐佐木| 亚洲乱码一区二区| 精品久久久中文| 久久国产色av| 国产精品黄色影片导航在线观看| 欧美视频第一页| 国产精品国产三级国产aⅴ浪潮| 欧美激情久久久久久| 精品久久久久久久久久久久久久| 亚洲男女性事视频| 中文字幕日韩免费视频| 2020欧美日韩在线视频| 欧美大胆在线视频| 亚洲精品小视频| 亚洲欧美激情在线视频| 欧美亚洲第一页| 欧美久久精品午夜青青大伊人|