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