摘要:剛剛發布,官網自稱最大的特點就是零配置。本文就詳細介紹一下實戰那些事兒。自動刷新監聽本地源代碼的變化,自動重新構建刷新瀏覽器。自動發布更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。代碼塊,一個由多個模塊組合而成,用于代碼合并與分割。
webpack4.0剛剛發布,官網自稱4.0最大的特點就是零配置。本文就詳細介紹一下webpack4.0實戰那些事兒。
1 什么是WebPack打包機
WebPack可以看做是模塊打包機:它做的事情是,分析你的項目結構,找到JavaScript模塊以及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),并將其打包為合適的格式以供瀏覽器使用。
構建
構建就是把源代碼轉換成發布到線上的可執行 JavaScrip、CSS、HTML 代碼,包括如下內容。
代碼轉換:TypeScript 編譯成 JavaScript、SCSS 編譯成 CSS 等。
文件優化:壓縮 JavaScript、CSS、HTML 代碼,壓縮合并圖片等。
代碼分割:提取多個頁面的公共代碼、提取首屏不需要執行部分的代碼讓其異步加載。
模塊合并:在采用模塊化的項目里會有很多個模塊和文件,需要構建功能把模塊分類合并成一個文件。
自動刷新:監聽本地源代碼的變化,自動重新構建、刷新瀏覽器。
代碼校驗:在代碼被提交到倉庫前需要校驗代碼是否符合規范,以及單元測試是否通過。
自動發布:更新完代碼后,自動構建出線上發布代碼并傳輸給發布系統。
構建其實是工程化、自動化思想在前端開發中的體現,把一系列流程用代碼去實現,讓代碼自動化地執行這一系列復雜的流程。 構建給前端開發注入了更大的活力,解放了我們的生產力。
2 快速配置 1 核心概念Entry:入口,Webpack 執行構建的第一步將從 Entry 開始,可抽象成輸入。
Module:模塊,在 Webpack 里一切皆模塊,一個模塊對應著一個文件。Webpack 會從配置的 Entry 開始遞歸找出所有依賴的模塊。
Chunk:代碼塊,一個 Chunk 由多個模塊組合而成,用于代碼合并與分割。
Loader:模塊轉換器,用于把模塊原內容按照需求轉換成新內容。
Plugin:擴展插件,在 Webpack 構建流程中的特定時機注入擴展邏輯來改變構建結果或做你想要的事情。
Output:輸出結果,在 Webpack 經過一系列處理并得出最終想要的代碼后輸出結果。
2 webpack的工作流程1 Webpack 啟動后會從Entry里配置的Module開始遞歸解析 Entry 依賴的所有 Module。
2 每找到一個 Module, 就會根據配置的Loader去找出對應的轉換規則,對 Module 進行轉換后,再解析出當前 Module 依賴的 Module。
3 這些模塊會以 Entry 為單位進行分組,一個 Entry 和其所有依賴的 Module 被分到一個組也就是一個 Chunk。
4 最后 Webpack 會把所有 Chunk 轉換成文件輸出。 在整個流程中 Webpack 會在恰當的時機執行 Plugin 里定義的邏輯。
3 配置webpack 1) 初始化npmnpm init -y
在要進行打包的目錄下初始化npm, 在控制臺執行以上命令后會生成一個package.json的文件。
2) installnpm install webpack webpack-cli -D
因為從4.0開始,webpack拆分開兩個包分別是webpack和webpack-cli
3) 配置文件webpack.config.jsmodule.exports = { entry:配置入口文件的地址 output:配置出口文件的地址 module:配置模塊,主要用來配置不同文件的加載器 plugins:配置插件 devServer:配置開發服務器 }
接下來我們就一一介紹一下它們的配置。
3 配置開發服務器 1 installnpm install webpack-dev-server -D2 配置參數
devServer:{ contentBase:path.resolve(__dirname,"dist"),// 配置開發服務運行時的文件根目錄 host:"localhost",// 開發服務器監聽的主機地址 compress:true, // 開發服務器是否啟動gzip等壓縮 port:8080 // 開發服務器監聽的端口 }3 配置啟動參數
"scripts": { "dev": "webpack-dev-server --open --mode development " }
note
從4.0開始,運行webpack時一定要加參數 --mode development 或者--mode production,分別對應開發環境和生產環境。
4 配置module 1 什么是loadermodule主要用來配置不同文件的加載器。談到加載就離不開loader,那什么是loader呢?
loader的概念
通過使用不同的Loader,Webpack可以要把不同的文件都轉成JS文件,比如CSS、ES6/7、JSX等。
test:匹配處理文件的擴展名的正則表達式
use:loader名稱,就是你要使用模塊的名稱
include/exclude:手動指定必須處理的文件夾或屏蔽不需要處理的文件夾
query:為loaders提供額外的設置選項
loader的三種寫法
use
loader
use+loader
2 支持加載css文件install
npm install style-loader css-loader -D
配置加載器
module: { rules:[ { test:/.css$/, use:["style-loader","css-loader"], include:path.join(__dirname,"./src"), exclude:/node_modules/ } ] }
note
注意:加載器的加載順序為從右至左。即先用css-loader解析然后用style-loader將解析后的css文件添加到Head標簽中。
3 支持圖片install
npm install file-loader url-loader html-withimg-loader -D
file-loader 解決CSS等文件中的引入圖片路徑問題
url-loader 當圖片較小的時候會把圖片BASE64編碼,大于limit參數的時候還是使用file-loader 進行拷貝
配置加載器
{ test: /.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)$/, loader: { loader: "url-loader", options: { limit: 5 * 1024,// 圖片大小 > limit 使用file-loader, 反之使用url-loader outputPath: "images/"http:// 指定打包后的圖片位置 } } }
usage - 手動添加圖片
let logo = require("./images/logo.png"); let img = new Image(); img.src = logo; document.body.appendChild(img);
usage - 在CSS中引入圖片
.img-bg{ background: url(./images/logo.png); width:173px; height:66px; }
usage - 在HTML中使用圖片
{ test:/.(html|html)$/, use:"html-withimg-loader", include:path.join(__dirname,"./src"), exclude:/node_modules/ }4 編譯less 和 sass 1) install
npm install less less-loader node-sass sass-loader -D2) 配置加載器
把編譯好的代碼放到head里面
{ test: /.css$/, loader: ["style-loader", "css-loader"] }, { test: /.less$/, loader: ["style-loader", "css-loader"] }, { test: /.scss$/, loader: ["style-loader", "css-loader"] }
把編譯好的代碼放到多帶帶的文件里面
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin"); let cssExtract = new ExtractTextWebpackPlugin("css.css"); let lessExtract = new ExtractTextWebpackPlugin("less.css"); let sassExtract = new ExtractTextWebpackPlugin("sass.css"); ... { test: /.css$/, loader: cssExtract.extract({ use: ["css-loader?minimize"] }) }, { test: /.less$/, loader: lessExtract.extract({ use: ["css-loader?minimize", "less-loader"] }) }, { test: /.scss$/, loader: sassExtract.extract({ use: ["css-loader?minimize", "sass-loader"] }) }5 處理CSS3屬性前綴
為了瀏覽器的兼容性,有時候我們必須加入-webkit,-ms,-o,-moz這些前綴
Trident內核:主要代表為IE瀏覽器, 前綴為-ms
Gecko內核:主要代表為Firefox, 前綴為-moz
Presto內核:主要代表為Opera, 前綴為-o
Webkit內核:產要代表為Chrome和Safari, 前綴為-webkit
install
npm install postcss-loader autoprefixer -D
usage
postcss-loader 需要配置 postcss.config.js文件,postcss.config.js 內容如下:
module.exports = { plugins: [ require("autoprefixer") ] }
// 把 post-laoder push 到css的loader數組中 { test: /.css$/, loader: ["style-loader", "css-loader", "postcss-loader"] }, { test: /.less$/, loader: ["style-loader", "css-loader", "less-loader"] }, { test: /.scss$/, loader: ["style-loader", "css-loader", "sass-loader"] }6 轉義ES6/ES7/JSX
Babel其實是一個編譯JavaScript的平臺,可以把ES6/ES7,React的JSX轉義為ES5。
install
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
配置加載器
{ test:/.jsx?$/, use: { loader: "babel-loader", options: { presets: ["env","stage-0","react"]// env --> es6, stage-0 --> es7, react --> react } }, include:path.join(__dirname,"./src"), exclude:/node_modules/ }5 配置plugins
配置插件
1 自動產出html我們希望自動能產出HTML文件,并在里面引入產出后的資源。
install
npm install html-webpack-plugin -D
usage
const HtmlWebpackPlugin = require("html-webpack-plugin"); plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", // 指定產出的模板 filename: "base.html", // 產出的文件名 chunks: ["common", "base"], // 在產出的HTML文件里引入哪些代碼塊 hash: true, // 名稱是否哈希值 title: "base", // 可以給模板設置變量名,在html模板中調用 htmlWebpackPlugin.options.title 可以使用 minify: { // 對html文件進行壓縮 removeAttributeQuotes: true // 移除雙引號 } }) ]2 分離CSS
因為CSS的下載和JS可以并行,當一個HTML文件很大的時候,我們可以把CSS多帶帶提取出來加載
install
npm install extract-text-webpack-plugin@next -D
usage
const ExtractTextWebpackPlugin = require("extract-text-webpack-plugin"); let cssExtract = new ExtractTextWebpackPlugin("css.css"); let lessExtract = new ExtractTextWebpackPlugin("less.css"); let sassExtract = new ExtractTextWebpackPlugin("sass.css"); ... module: { rules: [ { test: /.css$/, loader: cssExtract.extract({ use: ["css-loader?minimize"] }) }, { test: /.less$/, loader: lessExtract.extract({ use: ["css-loader?minimize", "less-loader"] }) }, { test: /.scss$/, loader: sassExtract.extract({ use: ["css-loader?minimize", "sass-loader"] }) } ] } ... plugins: [ cssExtract, lessExtract, sassExtract ]
處理圖片路徑問題
const PUBLIC_PATH="/"; output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js", publicPath:PUBLIC_PATH }3 拷貝靜態文件
有時項目中沒有引用的文件也需要打包到目標目錄
install
npm install copy-webpack-plugin -D
usage
const CopyWebpackPlugin = require("copy-webpack-plugin"); plugins: [ new CopyWebpackPlugin([{ from: path.join(__dirname, "public"), // 從哪里復制 to: path.join(__dirname, "dist", "public") // 復制到哪里 }]) ]4 打包前先清空輸出目錄
install
npm install clean-webpack-plugin -D
usage
const CleanWebpackPlugin = require("clean-webpack-plugin"); plugins: [ new CleanWebpackPlugin([path.join(__dirname, "dist")]) ]5 壓縮JS
install
npm install uglifyjs-webpack-plugin -D
usage
onst UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin"); plugins: [ new UglifyjsWebpackPlugin() ]6 如何調試打包后的代碼
webapck通過配置可以自動給我們source maps文件,map文件是一種對應編譯文件和源文件的方法
usage
devtool:"eval-source-map"
devtool的參數詳解
source-map 把映射文件生成到多帶帶的文件,最完整最慢
cheap-module-source-map 在一個多帶帶的文件中產生一個不帶列映射的Map
eval-source-map 使用eval打包源文件模塊,在同一個文件中生成完整sourcemap
cheap-module-eval-source-map sourcemap和打包后的JS同行顯示,沒有映射列
7 打包第三方類庫 1 直接引入import _ from "lodash"; alert(_.join(["a","b","c"],"@"));2 插件引入
new webpack.ProvidePlugin({ _:"lodash" })8 watch
當代碼發生修改后可以自動重新編譯
watch: true, watchOptions: { ignored: /node_modules/, //忽略不用監聽變更的目錄 aggregateTimeout: 500, // 文件發生改變后多長時間后再重新編譯(Add a delay before rebuilding once the first file changed ) poll:1000 //每秒詢問的文件變更的次數 }9 服務器代理
如果你有多帶帶的后端開發服務器 API,并且希望在同域名下發送 API 請求 ,那么代理某些 URL 會很有用。
//請求到 /api/users 現在會被代理到請求 http://localhost:9000/api/users。 proxy: { "/api": "http://localhost:9000", }10 resolve解析 1 extensions
指定extension之后可以不用在require或是import的時候加文件擴展名,會依次嘗試添加擴展名進行匹配
resolve: { //自動補全后綴,注意第一個必須是空字符串,后綴一定以點開頭 extensions: ["",".js",".css",".json"], },2 alias
配置別名可以加快webpack查找模塊的速度
每當引入jquery模塊的時候,它會直接引入jqueryPath,而不需要從node_modules文件夾中按模塊的查找規則查找
不需要webpack去解析jquery.js文件
const bootstrap = path.join(__dirname,"node_modules/bootstrap/dist/css/bootstrap.css"); resolve: { alias: { "bootstrap": bootstrap } }11 暴露全局對象
install
npm install expose-loader -D
action
把模塊的導出暴露給全局變量,
usage-1
require("expose-loader?libraryName!./file.js");
usage-2
rules: [{ test: require.resolve("jquery"),// 注意 這里是require的resolve 方法 use: { loader: "expose-loader", options: "$" } }]13 多入口
有時候我們的頁面可以不止一個HTML頁面,會有多個頁面,所以就需要多入口
usage
// 多個入口,可以給每個入口添加html模板 entry: { index: "./src/index.js", main:"./src/main.js" }, output: { path: path.resolve(__dirname, "dist"), filename: "[name].[hash].js", publicPath:PUBLIC_PATH }, plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, template: "./src/index.html", chunks:["index"], filename:"index.html" }), new HtmlWebpackPlugin({ minify: { removeAttributeQuotes:true }, hash: true, chunks:["login"], template: "./src/login.html", filename:"login.html" })] ]14 externals
如果我們想引用一個庫,但是又不想讓webpack打包,并且又不影響我們在程序中以CMD、AMD或者window/global全局等方式進行使用,那就可以通過配置externals。
webpack.config.js
externals: { jquery: "jQuery" //如果要在瀏覽器中運行,那么不用添加什么前綴,默認設置就是global },
index.js
const $ = require("jquery"); const $ = window.jQuery;15 參考文章
webpack官方文檔
webpack官方文檔中文版
webpackGitHub
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93862.html
摘要:配置以何種方式導出庫。當檢測文件不再發生變化,會先緩存起來,等等待一段時間后之后再通知監聽者,這個等待時間通過配置。發布到線上給用戶使用的運行環境。 一 縮小文件搜索范圍 1 include & exclude 1) action 限制編譯范圍 2) useage module: { rules: [ { test...
摘要:前言本文基于,主要涉及基本概念基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行優化配置。同一文件中,修改某個影響其他。 前言:本文基于weboack4.x,主要涉及webpack4 基本概念、基本配置和實際項目打包優化。關于概念方面參考官網,常用配置來自于網絡資源,在文末有相關參考鏈接,實踐部分基于自己的項目進行...
摘要:最近重構了一個項目,引入了部分用法,最大的感受是讓這門語言變得更加嚴謹,更加方便。通過該方法獲得位置后還得比較一次才能判斷是否存在。再來看看的寫法使用數組來初始化一個,構造器能確保不重復地使用這些值。下面提供鏈接,供有興趣的朋友參考。 最近重構了一個SPA項目,引入了部分ES6用法,最大的感受是ES6讓javascript這門語言變得更加嚴謹,更加方便。本篇將結合實戰經驗,對最常用的部...
摘要:設想下,如果有段程序,自動把你打開瀏覽器,然后跳轉到百度首頁。分為江湖傳言今年圣誕節會發布,主要是增強對移動端瀏覽器的測試。至于百度搜出來的那坨,誒,,往事不堪回首。這是面向用戶的最終測試。 一般來說對一個網站做測試,最直接的方法就是用手點,眼睛看。用手點和眼睛看把網站的功能點都過一遍,比如在百度首頁的搜索框里輸入 coding,點擊百度一下,用眼睛看會不會彈出有關 coding 的搜...
閱讀 3801·2021-11-24 09:39
閱讀 1810·2021-11-02 14:41
閱讀 814·2019-08-30 15:53
閱讀 3480·2019-08-29 12:43
閱讀 1189·2019-08-29 12:31
閱讀 3087·2019-08-26 13:50
閱讀 795·2019-08-26 13:45
閱讀 986·2019-08-26 10:56