日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Webpack核心概念解析

發布時間:2025/3/8 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Webpack核心概念解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接:banggan.github.io/2019/05/09/…

Webpack核心概念解析

終于忙完了論文,可以愉快的開始學習了,重拾起重學前端、webpack以及Vue的源碼解讀作為入職前的復習吧。整個webpack系列將分成五個大的部分進行,以webpack4.0為文檔進行解讀,從簡單的概念解讀到最后的實現。 整個知識點涉及范圍:

loader

使用loader來預處理文件,把不同的靜態資源(模塊的結尾不是js的模塊)打包成js文件

loader打包靜態資源

打包圖片

  • 安裝使用file-loader實現:npm install file-loader -D
  • 在webpack.config.js中添加loader的配置
module.exports = {//打包項目的入口文件entry: './src/index.js',module:{rules:[{test:/\.(jpg|png|gif)$/,//打包以jpg、png、gif結尾的所有圖片文件use:{loader:'file-loader',options:{//placeholder 占位符 name:'[name]_[hash].[ext]',//保持原圖片的名字+hash值和后綴,主要單引號outputPath:'image/'//打包圖片的位置}}}]} } 復制代碼
  • 更多的有關于file-loader的配置見文檔

打包圖片成base64格式

url-loader基本能實現file-loader的打包功能,適用于小圖片的打包

  • 好處:圖片打包成js文件,不用加載圖片的地址,頁面快速顯示
  • 壞處:圖片過大導致js文件過大

所以,當圖片的大小小于limit值時會把圖片打包成base64格式,大于limit值則按照file-loader打包成圖片文件

  • 安裝使用url-loader實現:npm install url-loader -D
  • 在webpack.config.js中添加loader的配置
module.exports = {module:{rules:[{//打包以jpg、png、gif結尾的所有圖片文件test:/\.(jpg|png|gif)$/,use:{loader:'url-loader',options:{//placeholder 占位符 name:'[name]_[hash].[ext]',//保持原圖片的名字+hash值和后綴,主要單引號outputPath:'image/',//打包圖片的位置limit:2048}}]} } 復制代碼
  • 更多的有關于url-loader的配置見文檔

打包樣式css文件

需要使用css-loader、style-loader

  • css-loader:分析幾個css文件的關系,合并css文件
  • style-loader:將css-loader合并的css內容掛載在頁面的head部分

實現方式:

  • 安裝loader實現:npm install css-loader style-loader -D
  • 在webpack.config.js中添加loader的配置
module.exports = {module: {rules: [{//打包css文件test:/\.css$/,use:['style-loader','css-loader']}]} } 復制代碼
  • 更多的有關于css-loader的配置見文檔

打包樣式scss文件

需要使用sass-loader、node-sass

  • 安裝loader實現:npm install sass-loader node-sass -D
  • 在webpack.config.js中添加loader的配置
module.exports = {module: {rules: [{test: /\.scss$/,use:['style-loader','css-loader','sass-loader'] }]} };復制代碼

在配置中,有三個loader,執行順序是從下到上,從右到左。在打包scss文件時,首先執行sass-loader:對sass翻譯成css文件,在掛載到css-loader,最后style-loader.

  • 更多的有關于sass-loader的配置見文檔

為樣式添加不同瀏覽器的前綴

為了兼容不同的瀏覽器,在寫樣式的時候需要加上適用不同瀏覽器的前綴,如-o、-webkit、-moz等

-安裝loader實現:npm install postcss-loader autoprefixer -D -在根目錄創建postcss.config.js

moudle.exports ={plugins:[require('autoprefixer')] } 復制代碼
  • 在webpack.config.js中添加loader的配置
module.exports = {module: {rules: [{test:/\.scss$/,use:['style-loader','css-loader','sass-loader','postcss-loader']}]} } 復制代碼
  • 更多的有關于postcss-loader的配置見文檔

css-loader添加不同的配置

css模塊化打包
  • 場景:在文件引入的scss不僅影響當前的文件,還影響當前文件引入的其他js文件,造成樣式沖突
  • 實現:css只在當前模塊類有效,在配置中添加modules:true開啟css的模塊化打包,在引入的時候注意區分
scss文件的嵌套引用
  • 場景:scss文件通過import引入其他scss文件,導致打包的時候引入的scss文件打包錯誤

  • 實現:importLoader:2

  • 在webpack.config.js中添加loader的配置

module:{rules:[{//打包scss文件test:/\.scss$/,use:['style-loader',{loader:'css-loader',options:{importLoaders:2,//index.scss中通過import引入其他的scss文件,引入的scss文件在打包的時候也將依次經過所有的loadermodules:true }},'sass-loader','postcss-loader']}]} 復制代碼

打包字體圖標文件

在阿里巴巴矢量圖標庫中,把需要的字體圖標下載到本地,解壓。將iconfont.eot iconfont.svg iconfont.ttf iconfont.woff 四種圖片文件放入到項目中,在src中新建一個放字體圖標的文件夾font。將iconfont.css文件拷貝到項目中,修改對應字體的引用路徑。

  • 需要安裝 file-loader:npm i file-loader -D
  • 在webpack.config.js中添加loader的配置
module.exports = {...module: {rules: [{test: /\.(eot|ttf|svg|woff)$/,use:{loader:'file-loader'}},]}]} } 復制代碼
  • 更多的有關于加載字體的配置見文檔

打包數據文件

如遇到json、scv、xml文件需要打包時,使用csv-loader 和 xml-loader實現。

  • 安裝:npm install csv-loader xml-loader -D
  • 在webpack.config.js中添加loader的配置
module.exports = {module: {rules: [{test: /\.(csv|tsv)$/,use: ['csv-loader']},{test: /\.xml$/,use: ['xml-loader']}]}} 復制代碼
  • 更多的有關于加載數據的配置見文檔

plugins

loaders可以將各個類型的靜態資源打包成webpack能處理的模塊,而plugins有更強大的功能。它可以從打包優化和壓縮,一直到重新定義環境中的變量。

plugin可以在webpack運行到某一個時刻,自動完成一些事情。

自動生成html文件,并引入打包生成的js文件到生成的html文件中

  • 安裝使用HtmlWebpackPlugin實現:npm install html-webpack-plugin -D
  • 在webpack.config.js中添加loader的配置

在src中創建一個html的模板,在HtmlWebpackPlugin的配置中引入該模板,打包后生成和模板類似的html文件并引入打包的js文件。

const HtmlWebpackPlugin = require('html-webpack-plugin'); const path = require('path');module.exports = {entry: 'index.js',output: {path: path.resolve(__dirname, './dist'),filename: 'index_bundle.js'},plugins: [new HtmlWebpackPlugin({template: 'src/index.html' })] } 復制代碼
  • 更多的有關于HtmlWebpackPlugin的配置見文檔

自動清除上一次打包的dist文件

先刪除上一次打包的dist文件,再執行打包

  • 安裝使用CleanWebpackPlugin 實現:npm install clean-webpack-plugin -D
  • 在webpack.config.js中添加loader的配置
const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const path = require('path');module.exports = {entry: 'index.js',output: {path: path.resolve(__dirname, './dist'),filename: 'index_bundle.js'},plugins: [new HtmlWebpackPlugin({template: 'src/index.html' }),new CleanWebpackPlugin(['dist']), // 在打包之前,可以刪除dist文件夾下的所有內容] } 復制代碼
  • 更多的有關于CleanWebpackPlugin的配置見文檔

Entry與Output的基礎配置

  • 需求:打包多個入口文件,對應的在出口的配置中注意命名filename避免出口文件名字沖突----使用占位符)來確保每個文件具有唯一的名稱
  • 需求:打包后的文件,作為后端的接口文件,靜態資源需要上傳到cdn,在output中進行配置,提前加入cdn的地址。在編譯時,如果不知道publicPath的地址,可以留空,在入口起點文件運行時動態設置。__webpack_public_path__ = myRuntimePublicPath
module.exports = {mode: 'development',entry: {main: './src/index.js',sub: './src/index.js'},plugins: [new HtmlWebpackPlugin({template: 'src/index.html'}), new CleanWebpackPlugin(['dist'])],output: {publicPath: 'http://cdn.com.cn', //加入cdn地址filename: '[name].js',path: path.resolve(__dirname, 'dist')} } 復制代碼
  • 更多的有關于output的配置見文檔

SourceMap的配置

SourceMap是一個映射關系,打包文件和源文件的映射關系,用于開發者的調試。

在devtool中進行設置:devtool: 'source-map'打包速度會降低,在dist里面會有map映射文件

常用設置devtool說明:

  • none:在開發者模式下,默認開啟sourcemap,將其關閉
  • inline前綴:不單獨生成map文件,把對應的map文件以base64的形式直接打包到js文件。
  • cheap前綴:sourcemap和打包后的js同行顯示,并沒有映射到列忽略源自 loader 的 source。 map,并且僅顯示轉譯后的代碼,所以打包速度相對來說較快。代碼出錯提示不用精確顯示第幾行的第幾個字符出錯,只顯示第幾行出錯,會提高一些性能,
  • moudle前綴:不僅映射業務代碼,還會包括loader、第三方模塊的錯誤。
  • eval前綴:打包速度最快。

development環境推薦使用: devtool: 'cheap-module-eval-source-map'

production環境推薦使用: devtool: 'cheap-module-source-map'

  • 更多的有關于devtool文檔

使用WebpackDevServer提升開發效率

場景:每次在src里編寫完代碼都需要手動重新運行 npm run bundle,如何自動解決?

-安裝:npm install webpack-dev-server –D

  • devServer參數說明
  • contentBase :配置開發服務運行時的文件根目錄
  • open :自動打開瀏覽器
  • host:開發服務器監聽的主機地址
  • compress :開發服務器是否啟動gzip等壓縮
  • port:開發服務器監聽的端口
    • 在 webpack.config.js 中,加 devServer
    const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin');module.exports = {mode: 'development',devtool: 'cheap-module-eval-source-map',devServer: {contentBase: './dist',open: true,port: 8080proxy:{//配置跨域,訪問的域名會被代理到本地的3000端口'/api': 'http://localhost:3000'}} } 復制代碼
    • 在 package.json 中配置
    {"name": "banggan","version": "1.0.0","description": "","main": "index.js","scripts": {"bundle": "webpack","watch": "webpack --watch","start": "webpack-dev-server",}, } 復制代碼
    • 更多的有關于devServer文檔

    如何實現自己寫一個類似webpackdevserver的工具

    • 在package.json 中配置 創建一個新的指令,npm run server運行自己寫的類似webpackdevserver的工具
    {"name": "banggan","version": "1.0.0","description": "","main": "index.js","scripts": {"bundle": "webpack","watch": "webpack --watch","start": "webpack-dev-server","server" : "node server.js" }, } 復制代碼
    • 安裝express:npm install express webpack-dev-middleware -D
    • 在根目錄創建一個server.js
    • 在node中直接使用webpack:webpack(config)
    const express = require('express'); //引入express const webpack = require('webpack');//引入webpack const webpackDevMiddleware = require('webpack-dev-middleware'); const config = require('./webpack.config.js');//引入配置文件const complier = webpack(config); //編譯一次嗎,打包一次代碼 const app = express();//創建express實例app.use(webpackDevMiddleware(complier, {}));app.listen(3000, () => {//監聽3000端口console.log('server is running'); }); 復制代碼

    Hot Module Replacement熱模塊更新

    • 場景:在程序運行中。替換、添加、替換某個模塊,不需要重新加載整個頁面,實現交互時更新。

    • 在 webpack.config.js 中,添加配置

    module.exports = {mode: 'development',devtool: 'cheap-module-eval-source-map',devServer: {contentBase: './dist',open: true,port: 8080,hot: true,//開啟熱更新功能hotOnly: true//如果html功能沒有實現,也不讓瀏覽器刷新},plugins: [new HtmlWebpackPlugin({template: 'src/index.html'}), new CleanWebpackPlugin(['dist']),new webpack.HotModuleReplacementPlugin()//使用熱模塊插件], } 復制代碼
    • 在main.js文件中,使用 HotModuleReplacementPlugin 啟用模塊的熱替換功能。接口暴露在moudle.hot屬性下面
    //如果模塊啟用了HMR,就可以用 module.hot.accept(),監聽模塊的更新。 if (module.hot) {module.hot.accept('./library.js', function() {// 使用更新過的 library 模塊執行某些操作...}) }復制代碼//拒絕給定依賴模塊的更新,使用 'decline' 方法強制更新失敗。 module.hot.decline(dependencies // 可以是一個字符串或字符串數組 ) 復制代碼

    注意:引入css文件時,用框架Vue,React 時,不需要寫 module.hot.accept(),因為在使用css-loader,vue-loader,babel-preset時,均配置好了HMR,不需要自己重新寫 如果文件沒有內置HMR,需要自己手動寫監聽模塊更新代碼

    結合Bable處理ES6語法

    • 場景:代碼中含有ES6/ES7的代碼,為了讓低版本的瀏覽器兼容代碼,需要使用Bable進行轉換
    • 安裝:Bable官網
    //preset-env語法轉換 npm install babel-loader @babel/core @babel/preset-env -D //兼容低版本瀏覽器的語法,函數的補充 npm install --save @babel/polyfill復制代碼
    • 在 webpack.config.js 中,添加配置
    module: {rules: [{test: /\.js$/,exclude: /node_modules/, //排除在外:在node_modules中的js,babel-loader不生效loader: "babel-loader" ,options:{"presets": [["@babel/preset-env",{targets: {edge: "17",firefox: "60",chrome: "67",safari: "11.1",},//運行在大于**版本的瀏覽器上,,已經支持es6的高瀏覽器不需要轉換為es5useBuiltIns:'usage' //按需添加polyfill,把業務代碼中的新語法新函數都轉成低版本瀏覽器兼容的}]]}}] }復制代碼
    • 在src目錄下的index.js中頂部位置導入import "@babel/polyfill";

    注意如果不是打包業務代碼,而是寫的類庫、或者z組件庫的時候不能使用@babel/polyfill實現,因為會導致聲明的變量變成全局變量,污染全局環境。使用plugin-transform-runtime實現

    • 安裝插件
    npm install --save-dev @babel/plugin-transform-runtime npm install --save @babel/runtime npm install --save @babel/runtime-corejs2復制代碼
    • 在 webpack.config.js 中,添加配置
    module: {rules: [{test: /\.js$/,exclude: /node_modules/,loader: "babel-loader" ,options:{"plugins": [["@babel/plugin-transform-runtime",{"corejs": 2,"helpers": true,"regenerator": true,"useESModules": false}]]}}] }復制代碼

    由于babel配置的內容較多,官網推薦在根目錄下創建屬于babel的配置文件.babelrc文件

    由于babel需要配置的內容非常多,我們需要在項目根目錄下創建一個 .babelrc 文件。 就不需要在 webpack.config.js 中寫 babel 的配置了。 在 .babelrc 中:

    {"plugins": [["@babel/plugin-transform-runtime", {"corejs": 2,"helpers": true,"regenerator": true,"useESModules": false}]] } 復制代碼

    總結

    • 在webpack.config.js中
    module.exports = {mode: 'development', //開發環境進行打包,打包的代碼不會壓縮devtool: 'cheap-module-eval-source-map',//不帶列信息,只對業務代碼進行sourcemap的生成 entry: {//配置入口文件main: './src/index.js'},devServer: {//配置webpack,開發環境的調試contentBase: './dist',//啟動服務器的目錄open: true,//打開新的端口號8080port: 8080,hot: true,//打開熱替換功能hotOnly: true},module: {//對不同的文件進行打包規則rules: [{ test: /\.js$/, //對js文件的babel-loader打包,其配置在.babelrc文件中exclude: /node_modules/, //排除在外:在node_modules中的js,babel-loader不生效loader: 'babel-loader',}, {test: /\.(jpg|png|gif)$/,//對圖片進行打包use: {loader: 'url-loader',options: {name: '[name]_[hash].[ext]',outputPath: 'images/',limit: 10240//小于10240以base64的形式進行打包}} }, {test: /\.(eot|ttf|svg)$/,//字體文件的打包use: {loader: 'file-loader'} }, {test: /\.scss$/,//scss文件的打包,先用postcss-loader,在用sass-loader進行解析,最后css-loader進行掛載use: ['style-loader', {loader: 'css-loader',options: {importLoaders: 2}},'sass-loader','postcss-loader']}, {test: /\.css$/,//css文件的打包,沒有sass-loader的解析use: ['style-loader','css-loader','postcss-loader']}]},plugins: [new HtmlWebpackPlugin({template: 'src/index.html'}), new CleanWebpackPlugin(['dist']),//自動清空上一次打包new webpack.HotModuleReplacementPlugin()//熱替換插件],output: {//出口文件filename: '[name].js',path: path.resolve(__dirname, 'dist')} } 復制代碼

    總結

    以上是生活随笔為你收集整理的Webpack核心概念解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。