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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

(十)webpack 和 babel

發布時間:2023/12/31 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (十)webpack 和 babel 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

webpack 和 babel

  • webpack
    • 面試題
    • 基本配置
      • 拆分配置和merge
      • 啟動本地服務
      • 處理ES6
      • 處理樣式
      • 處理圖片
      • 模塊化
      • 總結
    • 高級配置
      • 多入口
      • 抽離css文件
      • 抽離公共代碼
      • 懶加載
      • 處理JSX
      • 處理vue
      • module chunk bundle的區別
    • webpack性能優化
      • 構建速度
        • 優化babel-loader
        • IgnorePlugin避免引入無用的模塊
        • noParse避免重復打包
          • IgnorePlugin vs noParse
        • happyPack多進程打包
        • ParallelUglifyPlugin多進程壓縮JS
          • 關于開啟多進程
        • 自動刷新
        • 熱更新
        • DllPlugin動態鏈接庫插件
        • 總結
          • webpack優化構建速度(可用于生產環境)
          • webpack優化構建速度(不用于生產環境)
      • 優化產出代碼
        • 小圖片base64編碼
        • bundle加hash
        • 懶加載
        • 提取公共代碼
        • IgnorePlugin使打出體積更小
        • 使用CDN加速
        • 使用production
          • ES6 Module和commonjs的區別
        • Scope Hosting
    • babel
      • 環境搭建 & 基本配置
      • babel-polyfill
        • 什么是Polyfill
          • core-js和regenerator
          • babel-polyfill即兩者的集合
        • babel-polyfill如何按需引入
      • babel-runtime
        • babel-polyfill的問題
        • babel-runtime處理這個問題

webpack

webpack已是前端打包夠賤的不二選擇
每日必用,面試必考
成熟的工具,重點在于配置和使用,原理并不高優

面試題

  • 前端代碼為何要進行構建和打包
    代碼層面
    體積更小(Tree-Shaking、壓縮、合并)
    編譯高級語言或語法(TS、ES6+、模塊化、scss)
    兼容性和錯誤檢查(Polyfill、postcss、eslint)
    前端工程化、前端流程、團隊效率層面
    統一、高效的開發環境
    統一的構建流程和產出標準
    集成公司構建規范(提測、上線等)

  • module chunk bundle分別什么意思,有何區別?

  • loader和plugin的區別
    loader模塊轉換器,如less > css
    plugin擴展插件,如HtmlWebpackPlugin

  • 常見loader和plugin有哪些
    https://www.webpackjs.com/loaders/
    https://www.webpackjs.com/plugins/
    把此前示例中的loader和plugin答出來即可

  • webpack如何實現懶加載
    import()
    結合Vue React異步組件
    結合Vue-router React-router異步加載路由

  • webpack常見性能優化

  • babel-runtime和babel-polyfill的區別
    babel-polyfill會污染全局
    babel-runtime不會污染全局
    產出第三方lib要用babel-runtime

  • babel和webpack的區別
    babel - JS新語法編譯工具,不關心模塊化
    webpack - 打包構建工具,是多個loader plugin的集合

  • 如何產出一個lib
    參考webpack.dll.js
    output.library

  • 為何Proxy不能被polyfill
    如Class可以用function模擬
    如Promise可以用callback來模擬
    但Proxy的功能用Object.defineProperty無法模擬

基本配置

拆分配置和merge

const webpackCommonConf = require('./webpack.common.js') const { smart } = require('webpack-merge')module.exports = smart(webpackCommonConf, { })

啟動本地服務

devServer: {port: 8080,progress: true, // 顯示打包的進度條contentBase: distPath, // 根目錄open: true, // 自動打開瀏覽器compress: true, // 啟動 gzip 壓縮// 設置代理proxy: {// 將本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:3000',// 將本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:3000',pathRewrite: {'/api2': ''}}}}

處理ES6

{test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/ }, //.babelrc {"presets": ["@babel/preset-env"],"plugins": [] }

處理樣式

// {// test: /\.css$/,// // loader 的執行順序是:從后往前(知識點)// loader: ['style-loader', 'css-loader']// },{test: /\.css$/,// loader 的執行順序是:從后往前loader: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss},{test: /\.less$/,// 增加 'less-loader' ,注意順序loader: ['style-loader', 'css-loader', 'less-loader']} // postcss-loader是為了處理兼容性,還要配置postcss.config.js才會生效 //postcss.config.js module.exports = {plugins: [require('autoprefixer')] }

處理圖片

// dev直接引入圖片 url{test: /\.(png|jpg|jpeg|gif)$/,use: 'file-loader'}//prod情況小于 5kb 的圖片用 base64 格式產出,其他產出 url 格式放在img目錄下// 圖片 - 考慮 base64 編碼的情況{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的圖片用 base64 格式產出// 否則,依然延用 file-loader 的形式,產出 url 格式limit: 5 * 1024,// 打包到 img 目錄下outputPath: '/img1/',// 設置圖片的 cdn 地址(也可以統一在外面的 output 中設置,那將作用于所有靜態資源)// publicPath: 'http://cdn.abc.com'}}},

模塊化

總結

//package.json {"name": "07-webpack-demo","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","devBuild": "webpack --config build-optimization/webpack.dev.js","dev": "webpack-dev-server --config build-optimization/webpack.dev.js","build": "webpack --config build-optimization/webpack.prod.js"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.7.4","@babel/preset-env": "^7.7.4","autoprefixer": "^9.7.3","babel-loader": "^8.0.6","clean-webpack-plugin": "^3.0.0","css-loader": "^3.2.1","file-loader": "^5.0.2","happypack": "^5.0.1","html-webpack-plugin": "^3.2.0","less": "^3.10.3","less-loader": "^5.0.0","mini-css-extract-plugin": "^0.8.0","optimize-css-assets-webpack-plugin": "^5.0.3","postcss-loader": "^3.0.0","style-loader": "^1.0.1","terser-webpack-plugin": "^2.2.2","url-loader": "^3.0.0","webpack": "^4.41.2","webpack-cli": "^3.3.10","webpack-dev-server": "^3.9.0","webpack-merge": "^4.2.2","webpack-parallel-uglify-plugin": "^1.1.2"},"dependencies": {"lodash": "^4.17.15","moment": "^2.24.0"} } //paths.js /*** @description 常用文件夾路徑* @author 雙越*/const path = require('path')const srcPath = path.join(__dirname, '..', 'src') const distPath = path.join(__dirname, '..', 'dist')module.exports = {srcPath,distPath } //webpack.common.js const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const { srcPath, distPath } = require('./paths')module.exports = {entry: path.join(srcPath, 'index'),module: {rules: [{test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/},// {// test: /\.vue$/,// loader: ['vue-loader'],// include: srcPath// },// {// test: /\.css$/,// // loader 的執行順序是:從后往前(知識點)// loader: ['style-loader', 'css-loader']// },{test: /\.css$/,// loader 的執行順序是:從后往前loader: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss},{test: /\.less$/,// 增加 'less-loader' ,注意順序loader: ['style-loader', 'css-loader', 'less-loader']}]},plugins: [new HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html'})] } //webpack.dev.js const path = require('path') const webpack = require('webpack') const webpackCommonConf = require('./webpack.common.js') const { smart } = require('webpack-merge') const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'development',module: {rules: [// 直接引入圖片 url{test: /\.(png|jpg|jpeg|gif)$/,use: 'file-loader'}]},plugins: [new webpack.DefinePlugin({// window.ENV = 'development'ENV: JSON.stringify('development')})],devServer: {port: 8080,progress: true, // 顯示打包的進度條contentBase: distPath, // 根目錄open: true, // 自動打開瀏覽器compress: true, // 啟動 gzip 壓縮// 設置代理proxy: {// 將本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:3000',// 將本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:3000',pathRewrite: {'/api2': ''}}}} }) //webpack.prod.js const path = require('path') const webpack = require('webpack') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const webpackCommonConf = require('./webpack.common.js') const { smart } = require('webpack-merge') const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'production',output: {filename: 'bundle.[contentHash:8].js', // 打包代碼時,加上 hash 戳path: distPath,// publicPath: 'http://cdn.abc.com' // 修改所有靜態文件 url 的前綴(如 cdn 域名),這里暫時用不到},module: {rules: [// 圖片 - 考慮 base64 編碼的情況{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的圖片用 base64 格式產出// 否則,依然延用 file-loader 的形式,產出 url 格式limit: 5 * 1024,// 打包到 img 目錄下outputPath: '/img1/',// 設置圖片的 cdn 地址(也可以統一在外面的 output 中設置,那將作用于所有靜態資源)// publicPath: 'http://cdn.abc.com'}}},]},plugins: [new CleanWebpackPlugin(), // 會默認清空 output.path 文件夾new webpack.DefinePlugin({// window.ENV = 'production'ENV: JSON.stringify('production')})] }) //.babelrc {"presets": ["@babel/preset-env"],"plugins": [] } //postcss.config.js module.exports = {plugins: [require('autoprefixer')] }

高級配置

基本配置只能做demo,不能做線上項目
面試考察基本配置,只是為了快速判斷你是否用過webpack
以下高級配置,也是通過面試的必要條件

多入口

//webpack.common.jsentry: {index: path.join(srcPath, 'index.js'),other: path.join(srcPath, 'other.js')},// 多入口 - 生成 index.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html',// chunks 表示該頁面要引用哪些 chunk (即上面的 index 和 other),默認全部引用chunks: ['index'] // 只引用 index.js}),// 多入口 - 生成 other.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'other.html'),filename: 'other.html',chunks: ['other'] // 只引用 other.js}) //webpack.prod.js output: {// filename: 'bundle.[contentHash:8].js', // 打包代碼時,加上 hash 戳filename: '[name].[contentHash:8].js', // name 即多入口時 entry 的 keypath: distPath,// publicPath: 'http://cdn.abc.com' // 修改所有靜態文件 url 的前綴(如 cdn 域名),這里暫時用不到},

抽離css文件

//webpack.prod.js const path = require('path') const webpack = require('webpack') const { smart } = require('webpack-merge') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const TerserJSPlugin = require('terser-webpack-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') const webpackCommonConf = require('./webpack.common.js') const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'production',output: {// filename: 'bundle.[contentHash:8].js', // 打包代碼時,加上 hash 戳filename: '[name].[contentHash:8].js', // name 即多入口時 entry 的 keypath: distPath,// publicPath: 'http://cdn.abc.com' // 修改所有靜態文件 url 的前綴(如 cdn 域名),這里暫時用不到},module: {rules: [// 圖片 - 考慮 base64 編碼的情況{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的圖片用 base64 格式產出// 否則,依然延用 file-loader 的形式,產出 url 格式limit: 5 * 1024,// 打包到 img 目錄下outputPath: '/img1/',// 設置圖片的 cdn 地址(也可以統一在外面的 output 中設置,那將作用于所有靜態資源)// publicPath: 'http://cdn.abc.com'}}},// 抽離 css{test: /\.css$/,loader: [MiniCssExtractPlugin.loader, // 注意,這里不再用 style-loader'css-loader','postcss-loader']},// 抽離 less --> css{test: /\.less$/,loader: [MiniCssExtractPlugin.loader, // 注意,這里不再用 style-loader'css-loader','less-loader','postcss-loader']}]},plugins: [new CleanWebpackPlugin(), // 會默認清空 output.path 文件夾new webpack.DefinePlugin({// window.ENV = 'production'ENV: JSON.stringify('production')}),// 抽離 css 文件new MiniCssExtractPlugin({filename: 'css/main.[contentHash:8].css'})],optimization: {// 壓縮 cssminimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],} }) //webpack.dev.js const path = require('path') const webpack = require('webpack') const webpackCommonConf = require('./webpack.common.js') const { smart } = require('webpack-merge') const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'development',module: {rules: [// 直接引入圖片 url{test: /\.(png|jpg|jpeg|gif)$/,use: 'file-loader'},// {// test: /\.css$/,// // loader 的執行順序是:從后往前// loader: ['style-loader', 'css-loader']// },{test: /\.css$/,// loader 的執行順序是:從后往前loader: ['style-loader', 'css-loader', 'postcss-loader'] // 加了 postcss},{test: /\.less$/,// 增加 'less-loader' ,注意順序loader: ['style-loader', 'css-loader', 'less-loader']}]},plugins: [new webpack.DefinePlugin({// window.ENV = 'production'ENV: JSON.stringify('development')})],devServer: {port: 8080,progress: true, // 顯示打包的進度條contentBase: distPath, // 根目錄open: true, // 自動打開瀏覽器compress: true, // 啟動 gzip 壓縮// 設置代理proxy: {// 將本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:3000',// 將本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:3000',pathRewrite: {'/api2': ''}}}} }) //webpack.common.js const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const { srcPath, distPath } = require('./paths')module.exports = {entry: {index: path.join(srcPath, 'index.js'),other: path.join(srcPath, 'other.js')},module: {rules: [{test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/}// css 處理]},plugins: [// new HtmlWebpackPlugin({// template: path.join(srcPath, 'index.html'),// filename: 'index.html'// })// 多入口 - 生成 index.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html',// chunks 表示該頁面要引用哪些 chunk (即上面的 index 和 other),默認全部引用chunks: ['index'] // 只引用 index.js}),// 多入口 - 生成 other.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'other.html'),filename: 'other.html',chunks: ['other'] // 只引用 other.js})] }

抽離公共代碼

//webpack.prod.js const path = require('path') const webpack = require('webpack') const { smart } = require('webpack-merge') const { CleanWebpackPlugin } = require('clean-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const TerserJSPlugin = require('terser-webpack-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') const webpackCommonConf = require('./webpack.common.js') const { srcPath, distPath } = require('./paths')module.exports = smart(webpackCommonConf, {mode: 'production',output: {// filename: 'bundle.[contentHash:8].js', // 打包代碼時,加上 hash 戳filename: '[name].[contentHash:8].js', // name 即多入口時 entry 的 keypath: distPath,// publicPath: 'http://cdn.abc.com' // 修改所有靜態文件 url 的前綴(如 cdn 域名),這里暫時用不到},module: {rules: [// 圖片 - 考慮 base64 編碼的情況{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的圖片用 base64 格式產出// 否則,依然延用 file-loader 的形式,產出 url 格式limit: 5 * 1024,// 打包到 img 目錄下outputPath: '/img1/',// 設置圖片的 cdn 地址(也可以統一在外面的 output 中設置,那將作用于所有靜態資源)// publicPath: 'http://cdn.abc.com'}}},// 抽離 css{test: /\.css$/,loader: [MiniCssExtractPlugin.loader, // 注意,這里不再用 style-loader'css-loader','postcss-loader']},// 抽離 less{test: /\.less$/,loader: [MiniCssExtractPlugin.loader, // 注意,這里不再用 style-loader'css-loader','less-loader','postcss-loader']}]},plugins: [new CleanWebpackPlugin(), // 會默認清空 output.path 文件夾new webpack.DefinePlugin({// window.ENV = 'production'ENV: JSON.stringify('production')}),// 抽離 css 文件new MiniCssExtractPlugin({filename: 'css/main.[contentHash:8].css'})],optimization: {// 壓縮 cssminimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],// 分割代碼塊splitChunks: {chunks: 'all',/*** initial 入口 chunk,對于異步導入的文件不處理async 異步 chunk,只對異步導入的文件處理all 全部 chunk*/// 緩存分組cacheGroups: {// 第三方模塊vendor: {name: 'vendor', // chunk 名稱priority: 1, // 權限更高,優先抽離,重要!!!test: /node_modules/,minSize: 0, // 大小限制,多少kb才打包,為了防止比較小的包打包出來反而浪費資源minChunks: 1 // 最少復用過幾次 引用了一次就單獨抽離出},// 公共的模塊common: {name: 'common', // chunk 名稱priority: 0, // 優先級minSize: 0, // 公共模塊的大小限制,多少kb才打包,為了防止比較小的包打包出來反而浪費資源minChunks: 2 // 公共模塊最少復用過幾次 引用了2次就單獨抽離出}}}} }) //webpack.common.js const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const { srcPath, distPath } = require('./paths')module.exports = {entry: {index: path.join(srcPath, 'index.js'),other: path.join(srcPath, 'other.js')},module: {rules: [{test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/}]},plugins: [// new HtmlWebpackPlugin({// template: path.join(srcPath, 'index.html'),// filename: 'index.html'// })// 多入口 - 生成 index.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'index.html'),filename: 'index.html',// chunks 表示該頁面要引用哪些 chunk (即上面的 index 和 other),默認全部引用chunks: ['index', 'vendor', 'common'] // 要考慮代碼分割}),// 多入口 - 生成 other.htmlnew HtmlWebpackPlugin({template: path.join(srcPath, 'other.html'),filename: 'other.html',chunks: ['other', 'common'] // 考慮代碼分割})] }

懶加載

//引入動態數據 - 懶加載 setTimeout(() => {import('./dynamic-data.js').then(res=>{console.log(res.default.message) //注意這里的default}) },1500)

處理JSX

//.babelrc {"presets": ["@babel/preset-react"],"plugins": [] } //webpack配置 {test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/},

處理vue

{test: /\.vue$/,loader: ['vue-loader'],include: srcPath},

module chunk bundle的區別

module - 各個源碼文件,webpack中一切皆模塊,所有引入都是模塊,js、css、img都是模塊
chunk - 多模塊合并成的,如entry import() splitChunk
bundle - 最終的輸出文件,一般來說一個chunk對應一個bundle

module chunk bundle分別對應圖中的左中右

webpack性能優化

大廠必考 & 社區熱議話題
優化打包構建速度 - 開發體驗和效率
優化產出代碼 - 產品性能

構建速度

優化babel-loader


開啟緩存,es6代碼沒改的不會重新編譯

IgnorePlugin避免引入無用的模塊

import moment from ‘moment’
默認會引入所有語言JS代碼,代碼過大
如何只引入中文?

//webpack.prod.js// 忽略 moment 下的 /locale 目錄new webpack.IgnorePlugin(/\.\/locale/, /moment/),//index.jsimport moment from 'moment' import 'moment/locale/zh-cn' //手動引入中文語言 moment.locale('zh-cn')//設置語言為中文 console.log('locale',moment.locale) console.log('data',moment().format('ll')) //2020年xx月xx日

noParse避免重復打包

min,js基本上已經采用模塊化處理過的

IgnorePlugin vs noParse

IgnorePlugin 直接不引入,代碼中沒有
noParse引入,但不打包

happyPack多進程打包

JS單線程,開啟多進程打包
提高構建速度(特別是多核CPU)

const HappyPack = require('happypack'){test: /\.js$/,// 把對 .js 文件的處理轉交給 id 為 babel 的 HappyPack 實例use: ['happypack/loader?id=babel'],include: srcPath,// exclude: /node_modules/},// happyPack 開啟多進程打包new HappyPack({// 用唯一的標識符 id 來代表當前的 HappyPack 是用來處理一類特定的文件id: 'babel',// 如何處理 .js 文件,用法和 Loader 配置中一樣loaders: ['babel-loader?cacheDirectory']}),

ParallelUglifyPlugin多進程壓縮JS

webpack內置Uglify工具壓縮JS
JS單線程,開啟多進程壓縮更快
和happyPack同理

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')// 使用 ParallelUglifyPlugin 并行壓縮輸出的 JS 代碼 new ParallelUglifyPlugin({// 傳遞給 UglifyJS 的參數// (還是使用 UglifyJS 壓縮,只不過幫助開啟了多進程)uglifyJS: {output: {beautify: false, // 最緊湊的輸出comments: false, // 刪除所有的注釋},compress: {// 刪除所有的 `console` 語句,可以兼容ie瀏覽器drop_console: true,// 內嵌定義了但是只用到一次的變量collapse_vars: true,// 提取出出現多次但是沒有定義成變量去引用的靜態值reduce_vars: true,}} })
關于開啟多進程

項目較大,打包較慢,開啟多進程能提高速度
項目較小,打包更快,開啟多進程會降低速度(進程開銷)
按需使用

自動刷新

// watch: true, // 開啟監聽,默認為 false// watchOptions: {// ignored: /node_modules/, // 忽略哪些// // 監聽到變化發生后會等300ms再去執行動作,防止文件更新太快導致重新編譯頻率太高// // 默認為 300ms// aggregateTimeout: 300,// // 判斷文件是否發生變化是通過不停的去詢問系統指定文件有沒有變化實現的// // 默認每隔1000毫秒詢問一次// poll: 1000// }

//devServer會默認開啟自動刷新devServer: {port: 8080,progress: true, // 顯示打包的進度條contentBase: distPath, // 根目錄open: true, // 自動打開瀏覽器compress: true, // 啟動 gzip 壓縮hot: true,// 設置代理proxy: {// 將本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:3000',// 將本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:3000',pathRewrite: {'/api2': ''}}}},

熱更新

自動刷新:整個網頁全部刷新,速度較慢
自動刷新:整個網頁全部刷新,狀態會丟失
熱更新:新代碼生效,網頁不刷新,狀態不丟失

//webpack.dev.js const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');entry: {// index: path.join(srcPath, 'index.js'),index: ['webpack-dev-server/client?http://localhost:8080/','webpack/hot/dev-server',path.join(srcPath, 'index.js')]},plugins: [new HotModuleReplacementPlugin()],devServer: {port: 8080,progress: true, // 顯示打包的進度條contentBase: distPath, // 根目錄open: true, // 自動打開瀏覽器compress: true, // 啟動 gzip 壓縮hot: true,// 設置代理proxy: {// 將本地 /api/xxx 代理到 localhost:3000/api/xxx'/api': 'http://localhost:3000',// 將本地 /api2/xxx 代理到 localhost:3000/xxx'/api2': {target: 'http://localhost:3000',pathRewrite: {'/api2': ''}}}}, //index.js // 引入 css import './style/style1.css' import './style/style2.less'import { sum } from './math'const sumRes = sum(10, 20) console.log('sumRes', sumRes)// 增加,開啟熱更新之后的代碼邏輯if (module.hot) {module.hot.accept(['./math'], () => {const sumRes = sum(10, 30)console.log('sumRes in hot', sumRes)})}

DllPlugin動態鏈接庫插件

針對一些比較大的庫,第三方插件,沒有必要每次打包時都打包一遍,可以事先打包好以后作為dll.然后引用它

前端框架如vue React,體積大,構建慢
較穩定,不常升級版本
同一個版本只構建一次即可,不用每次都重新構建

webpack已內置DllPlugin支持
DllPlugin - 打包出dll文件
DllReferencePlugin - 使用dll文件

//package.json {"name": "08-webpack-dll-demo","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","dev": "webpack-dev-server --config build/webpack.dev.js","dll": "webpack --config build/webpack.dll.js"},"keywords": [],"author": "","license": "ISC","dependencies": {"react": "^16.12.0","react-dom": "^16.12.0"},"devDependencies": {"@babel/core": "^7.7.5","@babel/preset-env": "^7.7.5","@babel/preset-react": "^7.7.4","babel-loader": "^8.0.6","html-webpack-plugin": "^3.2.0","webpack": "^4.41.2","webpack-cli": "^3.3.10","webpack-dev-server": "^3.9.0","webpack-merge": "^4.2.2"} } //webpack.dll.js const path = require('path') const DllPlugin = require('webpack/lib/DllPlugin') const { srcPath, distPath } = require('./paths')module.exports = {mode: 'development',// JS 執行入口文件entry: {// 把 React 相關模塊的放到一個單獨的動態鏈接庫react: ['react', 'react-dom']},output: {// 輸出的動態鏈接庫的文件名稱,[name] 代表當前動態鏈接庫的名稱,// 也就是 entry 中配置的 react 和 polyfillfilename: '[name].dll.js',// 輸出的文件都放到 dist 目錄下path: distPath,// 存放動態鏈接庫的全局變量名稱,例如對應 react 來說就是 _dll_react// 之所以在前面加上 _dll_ 是為了防止全局變量沖突library: '_dll_[name]',},plugins: [// 接入 DllPluginnew DllPlugin({// 動態鏈接庫的全局變量名稱,需要和 output.library 中保持一致// 該字段的值也就是輸出的 manifest.json 文件 中 name 字段的值// 例如 react.manifest.json 中就有 "name": "_dll_react"name: '_dll_[name]',// 描述動態鏈接庫的 manifest.json 文件輸出時的文件名稱path: path.join(distPath, '[name].manifest.json'),}),], } npm run dll后dist文件夾下會生成react.dll.js和react.manifest.json //index.html<script src="./react.dll.js"></script> //webpack.dev.js// 第一,引入 DllReferencePlugin const DllReferencePlugin = require('webpack/lib/DllReferencePlugin');module: {rules: [{test: /\.js$/,loader: ['babel-loader'],include: srcPath,exclude: /node_modules/ // 第二,不要再轉換 node_modules 的代碼},]}, plugins: [// 第三,告訴 Webpack 使用了哪些動態鏈接庫new DllReferencePlugin({// 描述 react 動態鏈接庫的文件內容manifest: require(path.join(distPath, 'react.manifest.json')),}), ],

總結

webpack優化構建速度(可用于生產環境)

優化babel-loader
IgnorePlugin
noParse
happyPack
ParallelUglifyPlugin

webpack優化構建速度(不用于生產環境)

自動刷新
熱更新
DllPlugin

優化產出代碼

體積更小
合理分包,不重復加載
速度更快、內存使用更小

小圖片base64編碼

bundle加hash

懶加載

提取公共代碼

IgnorePlugin使打出體積更小

使用CDN加速

//webpack.prod.js中配置cdn地址output: {publicPath: 'http://cdn.abc.com' // 修改所有靜態文件 url 的前綴(如 cdn 域名),這里暫時用不到},{test: /\.(png|jpg|jpeg|gif)$/,use: {loader: 'url-loader',options: {// 小于 5kb 的圖片用 base64 格式產出// 否則,依然延用 file-loader 的形式,產出 url 格式limit: 5 * 1024,// 打包到 img 目錄下outputPath: '/img1/',// 設置圖片的 cdn 地址(也可以統一在外面的 output 中設置,那將作用于所有靜態資源)publicPath: 'http://cdn.abc.com'}} } 把靜態文件上傳至CDN

使用production

  • 自動開啟代碼壓縮
  • Vue React等會自動刪掉調試代碼(如開發環境的warning)
  • 啟動Tree-Shaking,沒有用到的方法不會加載,把沒有用的的搖掉
    // ES6 Module 才能讓 tree-shaking 生效
    // commonjs 就不行
ES6 Module和commonjs的區別

ES6 Module靜態引入,編譯時引入
Commonjs動態引入,執行時引入
只有ES6 Module才能靜態分析,實現Rree-Shaking

Scope Hosting



一個函數就有一個作用域,很多文件就會產生很多函數,很多作用域

開啟Scope Hosting之后,很多文件都放在一個函數里,作用域數量更少,內存占用更少,也不會頻繁的去跨作用域調用,JS代碼也會執行得快一些

代碼體積更小
創建函數作用域更少
代碼可讀性更好

babel

前端開發環境必備工具
同webpack,需要了解基本的配置和使用
面試考察概率不高,但要求必會

環境搭建 & 基本配置

  • 環境搭建
  • .babelrc配置
  • presets和plugins
//package.json {"name": "09-babel-demo","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/cli": "^7.7.5","@babel/core": "^7.7.5","@babel/plugin-transform-runtime": "^7.7.5","@babel/preset-env": "^7.7.5"},"dependencies": {"@babel/polyfill": "^7.7.0","@babel/runtime": "^7.7.5"} } //.babelrc {"presets": [["@babel/preset-env",{}]],"plugins": [] }

preset-env是一堆常用plugins的集合

//index.js const sum = (a,b) => a + b

npx babel src/index.js

babel-polyfill

什么是Polyfill

瀏覽器補丁、兼容

core-js和regenerator

標準庫,集成了ES6、ES7新語法的Polyfill

core-js不能處理generator函數,要用regenerator庫

babel-polyfill即兩者的集合

Babel7.4之后棄用babel-polyfill
推薦直接使用core-js和regenerator
但不影響面試會考察它

babel-polyfill如何按需引入

babel只關心語法,即便API不支持,只要語法符合規范,不管API,也不管模塊化

文件較大
只有一部分功能,無需全部引入
配置按需引入

//babelrc {"presets": [["@babel/preset-env",{"useBuiltIns": "usage","corejs": 3}]],"plugins": [] } //index.js const sum = (a, b) => a + b// 新的 API Promise.resolve(100).then(data => data);// 新的 API [10, 20, 30].includes(20)// 語法,符合 ES5 語法規范 // 不處理模塊化(webpack)


沒有使用babel-polyfill,直接引入core-js,babel-polyfill可以不用下載

babel-runtime

babel-polyfill的問題

  • 會污染全局環境
  • 如果做一個獨立的web系統,則無礙
  • 如果做一個第三方lib,則會有問題
// core.js要這樣處理,會污染全局環境 // window.Promise1 = function() {} // Array.prototype.includes1 = function () {}// 使用方可能這樣用,會出現問題 // window.Promise = 'abc' // Array.prototype.includes = 100

babel-runtime處理這個問題

devDependencies安裝 “@babel/plugin-transform-runtime”: “^7.7.5”,
dependencies安裝 “@babel/runtime”: “^7.7.5”

//.babelrc {"presets": [["@babel/preset-env",{"useBuiltIns": "usage","corejs": 3}]],"plugins": [["@babel/plugin-transform-runtime",{"absoluteRuntime": false,"corejs": 3,"helpers": true,"regenerator": true,"useESModules": false}]] }


配置后編譯出來的promise和includes前面有_,就不會有污染全局作用域問題

總結

以上是生活随笔為你收集整理的(十)webpack 和 babel的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 日本男女激情视频 | 中文字幕永久在线播放 | 富婆如狼似虎找黑人老外 | 91干网| 波多野结衣一二三区 | 日本午夜在线视频 | 精品久久BBBBB精品人妻 | 欧美伦理一区二区三区 | 成人在线网 | 三级av网站| 亚洲天堂精品在线观看 | 亚洲AV无码成人精品国产一区 | 91av中文字幕| 国产成人77亚洲精品www | 五月婷婷视频 | 麻豆精品久久久久久久99蜜桃 | 国产人妖ts重口系列网站观看 | 快色污| www.日本在线 | 国产精品第七页 | 亚洲乱妇老熟女爽到高潮的片 | 四虎在线免费视频 | 毛片基地在线播放 | 蜜桃精品在线 | 日韩性插 | 日韩欧美片 | 激情欧美一区二区三区精品 | jzzjzz日本丰满成熟少妇 | 男ji大巴进入女人视频 | 中文字幕亚洲图片 | 免费三级黄 | 亚洲最大黄色 | 爱草在线视频 | 日韩久 | 日韩视频一区二区三区四区 | 在线看片黄 | 亚洲精品中文在线 | 老鸭窝av在线 | 最新激情网| 成人网色| 日韩不卡免费视频 | 亚洲精品乱码 | 精品毛片 | 尹人综合网 | 人人干人人看 | 有奶水的迷人少妇 | 久久av一区二区三区 | 天天摸天天做天天爽 | 国产一级爱c视频 | 国产成人在线免费观看 | freesex性hd公交车上 | 国产精品熟女一区二区不卡 | www天堂网 | 三级在线看中文字幕完整版 | 海角社区在线视频播放观看 | 欧美日韩二区三区 | 综合在线视频 | 亚洲AV无码成人精品一区 | 我要操av | 国产麻豆电影在线观看 | 久久综合88 | 九色porny自拍视频在线播放 | 国产精品丝袜黑色高跟鞋的设计特点 | 午夜久久久久久久久久 | 国产精品一区在线 | 麻豆高清视频 | 夜夜嗨av一区二区三区 | 欧美激情视频在线观看 | 午夜寂寞剧场 | 黄色一级片一级片 | 中文字幕+乱码+中文字幕一区 | 污污视频免费网站 | 亚洲高清视频在线播放 | 黄色精彩视频 | 国产精品第100页 | 好吊色免费视频 | 91亚色| 亚洲欧美另类在线 | 亚洲一区二区影视 | 日本黄a| 久久精品无码一区二区三区免费 | 日韩私人影院 | 91免费观看视频在线 | 青青草视频国产 | 99在线精品视频免费观看软件 | 伊人久久爱 | 国产大尺度视频 | 国产在线观看免费视频软件 | 91成人免费在线观看视频 | 在线无| 99免费精品视频 | 2025av在线播放| www.在线观看麻豆 | 美女被揉胸视频 | 三级男人添奶爽爽爽视频 | 女人18毛片水真多 | 欧美性做爰猛烈叫床潮 | 波多野结衣中文字幕一区二区三区 | 国产精品永久 |