Webpack教程二
Webpack
- 1. watch觀察模式
- 2. webpack-dev-server
- 3. webpack-dev-middleware
- 4. HMR
- 5. Vue組件支持熱更新
- 6. 解析Resolve
- 7. source-map
- 8. devtool
- 9. 區(qū)分環(huán)境配置
1. watch觀察模式
在每一次修改代碼后,我們都要執(zhí)行npm run build 進(jìn)行打包,這樣不是很方便。為了簡(jiǎn)化流程,我們有兩種方式。
第一,可以在package.json中添加watch,之后每一次修改代碼保存后都會(huì)自動(dòng)打包一次。
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack --watch"},用VScode的Live Server打開(kāi)的頁(yè)面也會(huì)自動(dòng)更新
第二,在webpack.config.js中配置watch
module.exports={watch:true,... }2. webpack-dev-server
使用watch和live server可以實(shí)現(xiàn)自動(dòng)更新,但是其存在問(wèn)題為:
- 修改時(shí),所有源代碼都會(huì)重新編譯
- 每次編譯成功后都要進(jìn)行文件讀寫(xiě)(dist文件生成)
- 不能實(shí)現(xiàn)局部更新
這時(shí)我們需要webpack-dev-server, webpack-dev-server為你提供了一個(gè)簡(jiǎn)單的 web 服務(wù)器,并且能夠實(shí)時(shí)重新加載。
1、下載
npm i webpack-dev-server -D2、在package.json中配置serve如下
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","serve": "webpack serve" },3、在終端執(zhí)行npm run serve,這時(shí)并不會(huì)生成dist文件,而是將資源保存在內(nèi)存中。我們可以使用http://localhost:8080/打開(kāi)頁(yè)面,從而使我們的資源運(yùn)行在一個(gè)本地服務(wù)器上。
除此之外,我們還可以在webpack.config.js中配置devServer。
devServer:{static:{// 此路徑下的打包文件可在瀏覽器中訪問(wèn)。//默認(rèn) publicPath 是 "/",所以你的包index.js可以通過(guò) http://localhost:8080/index.js 訪問(wèn)。publicPath:'/lg/',} },這時(shí)如果把output.publicPath也設(shè)置為'/lg'則可以在該目錄下正確訪問(wèn)頁(yè)面
其他配置:
3. webpack-dev-middleware
webpack-dev-middleware 是一個(gè)容器,它可以把 webpack 處理后的文件傳遞給一個(gè)服務(wù)器。
// express框架用于搭建web服務(wù)器 npm i express npm i webpack-dev-middlewareexpress框架的基本使用可以看這一篇文章
const webpackDevMiddleware=require('webpack-dev-middleware') const webpack = require('webpack')const express = require('express') const app = express()// 獲取配置文件 const config = require('./webpack.config.js') const compiler = webpack(config)app.use(webpackDevMiddleware(compiler))//開(kāi)啟端口上的服務(wù) app.listen(3000,()=>{console.log('服務(wù)器運(yùn)行在3000端口'); })這樣我們就可以訪問(wèn)express所搭建的服務(wù)器資源了
4. HMR
模塊熱替換(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允許在運(yùn)行時(shí)更新各種模塊,而無(wú)需進(jìn)行完全刷新。
也就是說(shuō)如果當(dāng)你更新一個(gè)模塊的代碼時(shí),其他未修改的代碼不會(huì)受影響,重新更新。
1、webpack.config.js中的配置如下
module.exports={...devServer:{hot:true} }2、在入口文件index.js中指定要熱替換的模塊
if(module.hot){module.hot.accept(['./title.js'],()=>{console.log('title模塊更新啦~');}) }3、局部更新
5. Vue組件支持熱更新
Vue Loader支持用于 vue 組件的 HMR,提供開(kāi)箱即用體驗(yàn)。
1、下載
npm i vue@2 -D npm i vue-loader@14 -D2、webpack.config.js中進(jìn)行配置
{test:/\.vue$/,use:['vue-loader']}3、示例
index.js
import './title' import Vue from 'vue' import App from './App.vue'new Vue({render:h=>h(App) }).$mount('#root')app.vue
<template><div class='one'>{{msg}}</div> </template><script> export default{data(){return{msg:'hello!'}} } </script><style>.one{color:red;} </style>如下:
6. 解析Resolve
Resolve配置可以設(shè)置模塊如何被解析
絕對(duì)路徑:不需要進(jìn)行解析
相對(duì)路徑:在 import/require 中給定的相對(duì)路徑,會(huì)拼接此上下文路徑,來(lái)生成模塊的絕對(duì)路徑。
模塊路徑:在 resolve.modules 中指定的所有目錄中檢索模塊。
modules: ['node_modules']
一旦根據(jù)上述規(guī)則解析路徑后,resolver 將會(huì)檢查路徑是指向文件還是文件夾。
如果路徑指向文件:
- 如果文件具有擴(kuò)展名,則直接將文件打包。
- 否則,將使用 resolve.extensions 選項(xiàng)作為文件擴(kuò)展名來(lái)解析,此選項(xiàng)會(huì)告訴解析器在解析中能夠接受那些擴(kuò)展名(例如 .js,.jsx)。
如果路徑指向一個(gè)文件夾,則進(jìn)行如下步驟尋找具有正確擴(kuò)展名的文件:
- 如果文件夾中包含 package.json 文件,則會(huì)根據(jù) resolve.mainFields 配置中的字段順序查找,并根據(jù) package.json 中的符合配置要求的第一個(gè)字段來(lái)確定文件路徑。
- 如果不存在 package.json 文件或 resolve.mainFields 沒(méi)有返回有效路徑,則會(huì)根據(jù) resolve.mainFiles 配置選項(xiàng)中指定的文件名順序查找,看是否能在 import/require 的目錄下匹配到一個(gè)存在的文件名。
- 然后使用 resolve.extensions 選項(xiàng),以類(lèi)似的方式解析文件擴(kuò)展名。
resolve.alias用于創(chuàng)建 import 或 require 的別名,來(lái)確保模塊引入變得更簡(jiǎn)單。例如,一些位于 src/ 文件夾下的常用模塊:
resolve: {alias: {@: path.resolve(__dirname, 'src')},},原本導(dǎo)入如下
import './title'現(xiàn)在導(dǎo)入
import '@/title'7. source-map
當(dāng) webpack 打包源代碼時(shí),可能會(huì)很難追蹤到 error(錯(cuò)誤) 和 warning(警告) 在源代碼中的原始位置。例如,如果將三個(gè)源文件(a.js, b.js 和 c.js)打包到一個(gè) bundle(bundle.js)中,而其中一個(gè)源文件包含一個(gè)錯(cuò)誤,那么堆棧跟蹤就會(huì)直接指向到 bundle.js。
為了更容易地追蹤 error 和 warning,JavaScript 提供了 source maps 功能,可以將編譯后的代碼映射回原始源代碼。如果一個(gè)錯(cuò)誤來(lái)自于 b.js,source map 就會(huì)明確的告訴你。
瀏覽器中要sour允許使用source-map
8. devtool
devtool用于選擇一種 source map 風(fēng)格來(lái)增強(qiáng)調(diào)試過(guò)程。不同的值會(huì)明顯影響到構(gòu)建(build)和重新構(gòu)建(rebuild)的速度。
- 對(duì)于開(kāi)發(fā)環(huán)境,通常希望更快速的 source map,需要添加到 bundle 中以增加體積為代價(jià)
- 對(duì)于生產(chǎn)環(huán)境,則希望更精準(zhǔn)的 source map,需要從 bundle 中分離并獨(dú)立存在。
以下選項(xiàng)非常適合開(kāi)發(fā)環(huán)境:
- eval - 每個(gè)模塊都使用 eval() 執(zhí)行,并且都有 //@ sourceURL。此選項(xiàng)會(huì)非常快地構(gòu)建。主要缺點(diǎn)是,由于會(huì)映射到轉(zhuǎn)換后的代碼,而不是映射到原始代碼(沒(méi)有從 loader 中獲取 source map),所以不能正確的顯示行數(shù)。
- eval-source-map - 每個(gè)模塊使用 eval() 執(zhí)行,并且 source map 轉(zhuǎn)換為 DataUrl 后添加到 eval() 中。初始化 source map 時(shí)比較慢,但是會(huì)在重新構(gòu)建時(shí)提供比較快的速度,并且生成實(shí)際的文件。行數(shù)能夠正確映射,因?yàn)闀?huì)映射到原始代碼中。它會(huì)生成用于開(kāi)發(fā)環(huán)境的最佳品質(zhì)的 source map。
- eval-cheap-source-map - 類(lèi)似 eval-source-map,每個(gè)模塊使用 eval() 執(zhí)行。這是 “cheap(低開(kāi)銷(xiāo))” 的 source map,因?yàn)樗鼪](méi)有生成列映射(column mapping),只是映射行數(shù)。它會(huì)忽略源自 loader 的 source map,并且僅顯示轉(zhuǎn)譯后的代碼,就像 eval devtool。
- eval-cheap-module-source-map - 類(lèi)似 eval-cheap-source-map,并且,在這種情況下,源自 loader 的 source map 會(huì)得到更好的處理結(jié)果。然而,loader source map 會(huì)被簡(jiǎn)化為每行一個(gè)映射(mapping)。
這些選項(xiàng)通常用于生產(chǎn)環(huán)境中:
- (none)(省略 devtool 選項(xiàng)) - 不生成 source map。這是一個(gè)不錯(cuò)的選擇。
- source-map - 整個(gè) source map 作為一個(gè)單獨(dú)的文件生成。它為 bundle 添加了一個(gè)引用注釋,以便開(kāi)發(fā)工具知道在哪里可以找到它。
以下選項(xiàng)對(duì)于開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境并不理想。他們是一些特定場(chǎng)景下需要的,例如,針對(duì)一些第三方工具。
- inline-source-map - source map 轉(zhuǎn)換為 DataUrl 后添加到 bundle 中。
- cheap-source-map - 沒(méi)有列映射(column mapping)的 source map,忽略 loader source map。
- inline-cheap-source-map - 類(lèi)似 cheap-source-map,但是 source map 轉(zhuǎn)換為 DataUrl 后添加到 bundle 中。
- cheap-module-source-map - 沒(méi)有列映射(column mapping)的 source map,將 loader source map 簡(jiǎn)化為每行一個(gè)映射(mapping)。
- inline-cheap-module-source-map - 類(lèi)似 cheap-module-source-map,但是 source mapp 轉(zhuǎn)換為 DataUrl 添加到 bundle 中。
9. 區(qū)分環(huán)境配置
在開(kāi)發(fā)環(huán)境中,我們需要強(qiáng)大的 source map 和一個(gè)有著 live reloading(實(shí)時(shí)重新加載) 或 hot module replacement(熱模塊替換) 能力的 localhost server。
而生產(chǎn)環(huán)境目標(biāo)則轉(zhuǎn)移至其他方面,關(guān)注點(diǎn)在于壓縮 bundle、更輕量的 source map、資源優(yōu)化等,通過(guò)這些優(yōu)化方式改善加載時(shí)間。
由于要遵循邏輯分離,建議為每個(gè)環(huán)境編寫(xiě)彼此獨(dú)立的 webpack 配置。
當(dāng) webpack 配置對(duì)象導(dǎo)出為一個(gè)函數(shù)時(shí),可以向起傳入一個(gè)"環(huán)境對(duì)象(environment)"。
"scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","serve": "webpack serve","build2": "webpack --config ./config/webpack.common.js --env production","serve2": "webpack serve --config ./config/webpack.common.js --env development"},根據(jù)CLI命令絕對(duì)配置文件
// webpack-merge 提供一個(gè)merge函數(shù)用于合并數(shù)組,或者對(duì)象 const {merge} = require('webpack-merge')const prodConfig = require('./webpack.prod') const devConfig = require('./webpack.dev') const commonConfig={//基本配置 } module.exports=(env)=>{const isProduction = env.Production;const config = isProduction?prodConfig:devConfig;const mergeConfig=merge(commonConfig,config)return mergeConfig }總結(jié)
以上是生活随笔為你收集整理的Webpack教程二的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: WSF操作系统抽象层学习笔记 (五)--
- 下一篇: LS-DYNA钢筋拉伸试验仿真