国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

前端工程化之 webpack <一>

這篇具有很好參考價(jià)值的文章主要介紹了前端工程化之 webpack <一>。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、 Webpack 和打包過(guò)程

編寫(xiě)的代碼 ==》經(jīng)過(guò)打包工具(glup、rollup、webpack、vite)本身也是js代碼,讀取文件操作的,依賴于 node 環(huán)境

= = 》 普通的html 、css 、javascript

= = 》 打包到靜態(tài)服務(wù)器

= = 》 跑在用戶的瀏覽器

1.1 內(nèi)置模塊 path

  • 用于對(duì)路徑和文件進(jìn)行處理
  • 在 Mac OS、Linux 和 window 上的路徑上是不一樣的,部署的時(shí)候顯示路徑會(huì)出現(xiàn)一些問(wèn)題,為了屏蔽他們之間的差異,在開(kāi)發(fā)中對(duì)于路徑的操作可以使用 path模塊
const path = require("path");

// 幫助我們從路徑當(dāng)中獲取一些信息
const filepath = "C://abc/cba/nba.txt";

// 1. 可以從一個(gè)路徑中獲取一些信息
// 1.1 拿到文件的后綴名
console.log(path.extname(filepath));
// 1.2 獲取文件名
console.log(path.basename(filepath));
// 1.3 獲取文件夾
console.log(path.dirname(filepath));

const path1 = "/abc/cba";
const path2 = "../../lili/kobe/james.txt";
// 2. 將多個(gè)路徑拼接在一起
console.log(path.join(path1, path2));
// 3. 將多個(gè)路徑拼接在一起,最終返回一個(gè)絕對(duì)路徑: path.resolve
console.log("-----resolve------");
// 從右向左依次處理,形成了絕對(duì)路徑就不會(huì)繼續(xù)往前找了
console.log(path.resolve(path1, path2,"/abc.txt"));

1.2 認(rèn)識(shí) webpack

  • 隨著前端的快速發(fā)展,目前前端的開(kāi)發(fā)已經(jīng)越來(lái)越復(fù)雜
    • 模塊化的方式進(jìn)行開(kāi)發(fā)
    • 使用高級(jí)的特性來(lái)加快我們的開(kāi)發(fā)效率或者安全性
    • 實(shí)時(shí)監(jiān)聽(tīng)文件的變化,反映到瀏覽器上,提高開(kāi)發(fā)的效率
    • 將代碼進(jìn)行壓縮、合并以及其他相關(guān)的優(yōu)化
  • 腳手架依賴 webpack
    • vue:cli-service
    • react:config
    • angular
  • webpack is a static module bundler for modern javascript application
    • 靜態(tài)的:打包成普通的靜態(tài)文件:html 、 css 、js
    • 模塊化:common.js、amd 、cmd、
    • 現(xiàn)代的:應(yīng)用程序復(fù)雜,才催生了webpack
    • 打包工具:本質(zhì)是幫我們進(jìn)行打包的

1.3 vue 項(xiàng)目加載的文件

  • javascript 的打包
    • 將 es6 轉(zhuǎn)成es5
    • ts 轉(zhuǎn)成 js
  • css 的處理
    • css 文件模塊的加載、提取
    • less、sass 等預(yù)處理器的處理
  • 資源文件 img、font
    • 字體 font 文件的加載
    • 圖片 img 文件的加載
  • html 資源的處理
    • 打包 html 資源文件
  • 處理 vue 項(xiàng)目的 sfc 文件 .vue 文件

1.4 webpack 的使用

  • webpack 、webpack-cli
    • webpack-cli:識(shí)別命令行
  • 局部安裝npm i webpack webpack-cli -D
  • 使用局部的npx webpack后面可以跟參數(shù)
  • 配置參數(shù)很多,可以寫(xiě)到一個(gè)單獨(dú)的文件里面:webpack.config.js – webpack 配置文件
const path = require("path");
module.exports = {
  // 配置入口
  entry: "./src/index.js",
  // 配置出口
  output: {
    filename: "bundle.js",
    // 必須是絕對(duì)路徑
    path: path.resolve(__dirname, "./build"),
  },
};

1.5 webpack 形成的依賴圖

  • 從入口開(kāi)始,會(huì)生成一個(gè)依賴關(guān)系圖,會(huì)包含應(yīng)用程序中所需的所有模塊(.js文件、css文件、圖片、字體)
  • 遍歷圖結(jié)構(gòu),打包一個(gè)個(gè)模塊
  • 根據(jù)文件的不同使用不同的 loader 來(lái)解析

1.6 loader

  • loader
    • loader 可以用于對(duì)模塊的源代碼進(jìn)行轉(zhuǎn)換
    • 將 css 文件也看成是一個(gè)模塊,通過(guò) import 來(lái)加載這個(gè)模塊
    • 在加載這個(gè)模塊的時(shí)候,webpack 其實(shí)并不知道如何進(jìn)行加載,必須制定相應(yīng)的規(guī)則去完成這個(gè)功能
    • 配置文件 =》module =》rules
      • 匹配 .vue=>使用 vue.loader
      • 匹配 .css=>使用 css.loader
  • 默認(rèn) webpack 會(huì)處理 js 文件
  • 配置方式
    • module{}
      • rules[]
        • {
        • test
        • use:多個(gè) loader 的使用規(guī)則是從后往前的
        • }

1.7 css-loader

  • 安裝:npm i css-loader -D
  • 配置規(guī)則
  module: {
    // 規(guī)則很多,對(duì)應(yīng)的是數(shù)組類型
    rules: [
      // 數(shù)組里面放對(duì)象
      {
        // 告訴webpack 要匹配什么文件
        test: /\.css$/,
        // 要使用哪些loader
        use: [{ loader: "css-loader" }],
      },
    ],
  },
  • 只負(fù)責(zé)解析 css 文件,并不負(fù)責(zé)插入到頁(yè)面中

1.8 style-loader

  • 插入 style
  • 安裝:npm i style-loader -D
const path = require("path");
module.exports = {
  // 配置rukou
  entry: "./src/index.js",
  // 配置出口
  output: {
    filename: "bundle.js",
    // 必須是絕對(duì)路徑
    path: path.resolve(__dirname, "./build"),
  },
  module: {
    // 規(guī)則很多,對(duì)應(yīng)的是數(shù)組類型
    rules: [
      // 數(shù)組里面放對(duì)象
      {
        // 告訴webpack 要匹配什么文件
        test: /\.css$/,
        // 要使用哪些loader
        use: [{ loader: "style-loader" }, { loader: "css-loader" }],
      },
    ],
  },
};

  • 簡(jiǎn)寫(xiě)
   test: /\.css$/,
        // 要使用哪些loader
        // use: [{ loader: "style-loader" }, { loader: "css-loader" }],
        // 簡(jiǎn)寫(xiě)一:如果 Loader 只有一個(gè)
        // loader: 'css-loader'
        // 簡(jiǎn)寫(xiě)二:多個(gè)loader不需要配置其他options
        use: ["style-loader", "css-loader"],

1.9 less-loader

  • 前提需要安裝 less
  • 安裝:npm i less-loader -D
  • 配置
     {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },

1.10 postcss-loader

  • 安裝:npm i postcss-loader -D

  • 使用:use: ["style-loader", "css-loader", "postcss-loader"]

  • postcss 介紹

    • 通過(guò) javascript 來(lái)轉(zhuǎn)換樣式的工具
    • 這個(gè)工具可以幫助我們進(jìn)行一些 css 的轉(zhuǎn)換和適配,比如自動(dòng)添加瀏覽器前綴、css樣式的重置
    • 需要借助 對(duì)應(yīng)的插件
      • 安裝:npm i autoprefixer -D
  • 重新配置

    • options 里面添加的東西會(huì)被 loader 讀取
     {
            // 告訴webpack 要匹配什么文件
            test: /\.css$/,
            use: [
              "style-loader",
              "css-loader",
              {
                loader: "postcss-loader",
                options: {
                  postcssOptions: {
                    plugins: [
                      "autoprefixer"
                    ]
                  },
                },
              },
            ],
          },
    
    • 這樣就能實(shí)現(xiàn)添加瀏覽器前綴
  • 太臭太長(zhǎng)了,在項(xiàng)目目錄中里面創(chuàng)建文件postcss.config.js

    • 當(dāng)寫(xiě)成簡(jiǎn)寫(xiě)的時(shí)候沒(méi)有配置對(duì)應(yīng)的 options,就會(huì)自己讀取這個(gè)文件
    module.exports = {
      plugins: ["autoprefixer"],
    };
    
    
  • 因?yàn)橛邢旅孢@個(gè),所以卸載它:npm uninstall autoprefixer

  • 也可以使用另外的插件postcss-preset-env預(yù)設(shè)環(huán)境

    • 可以將一些現(xiàn)代的 css 特性,轉(zhuǎn)成大多數(shù)瀏覽器認(rèn)識(shí)的 css ,并且會(huì)根據(jù)目標(biāo)瀏覽器或者運(yùn)行時(shí)環(huán)境添加所需的 polyfill
      • bgc-color:#666666==》 rgba 的格式
    • 包括 autoprefixer
    • 安裝:npm install postcss-preset-env -D

1.11 Webpack打包圖片-JS-Vue

  • 現(xiàn)代的前端開(kāi)發(fā)模式中,根本不需要手動(dòng)添加瀏覽器前綴
  • 引入圖片模塊:import 圖片名字 from "../img/zznh.png"
    • 可以給這個(gè)模塊起一個(gè)名字
  • 早期加載資源使用:npm i file-loader
    • 在最新的版本已經(jīng)不用這個(gè)東西了
    • webpack5之后使用資源模塊類型開(kāi)替代這些loader
      • raw-loader、url-loader、file-loader
  {
        test: /\.(png|jpe?g|svg|gif)$/,
        // 當(dāng)成資源類型
        type:"assets"
      },

1.12 資源模塊類型

  • asset/resource:發(fā)送一個(gè)單獨(dú)的文件并導(dǎo)出 URL
    • 缺點(diǎn):多了 http 網(wǎng)絡(luò)請(qǐng)求(幾張圖片就幾次)
  • asset**/inline**:導(dǎo)出一個(gè)資源的 data URL
    • 優(yōu)點(diǎn):可以少發(fā)送兩次請(qǐng)求
    • 缺點(diǎn):造成 js 文件很大,下載 、解析js 文件時(shí)間非常長(zhǎng)
  • asset/source:導(dǎo)出資源的源代碼
  • asset
    • 使用過(guò)程
      • 將 type 改成 asset
      • 添加 parser 屬性,并且制定 dataUrl 的條件
        • maxSize
const { type } = require("os");
const path = require("path");
const { webpack } = require("webpack");
module.exports = {
  // 配置rukou
  entry: "./src/index.js",
  // 配置出口
  output: {
    filename: "bundle.js",
    // 必須是絕對(duì)路徑
    path: path.resolve(__dirname, "./build"),
    // assetModuleFilename: "abc.png",//很少在這配置
  },
  module: {
    // 規(guī)則很多,對(duì)應(yīng)的是數(shù)組類型
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
      {
        test: /\.less$/,
        use: ["style-loader", "css-loader", "less-loader"],
      },
      {
        test: /\.(png|jpe?g|svg|gif)$/,
        // 當(dāng)成資源類型
        // type: "asset"
        // 1. 打包兩張圖片,并且這兩張圖片有自己的地址,將地址設(shè)置到img/bgi中
        // type:"asset/resource"
        // 2. 把圖片進(jìn)行 base64 編碼,并且直接將編碼后的源碼放在打包的js文件中

        // type: "asset/inline"

        // 合理的規(guī)范
        // 1 對(duì)于小一點(diǎn)的圖片,可以進(jìn)行base64的編碼
        // 2 對(duì)于大一點(diǎn)的圖片,單獨(dú)的圖片打包,形成 url 地址,單獨(dú)的請(qǐng)求這個(gè) url 文件
        // 由此誕生了asset
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 60 * 1024,
          },
        },
        // 設(shè)置文件名
        generator: {
          // 一般名字不寫(xiě)死,寫(xiě)上占位符
          // name:指向原來(lái)的圖片名稱
          // ext(擴(kuò)展名):直接帶點(diǎn)
          // hash:webpack生成的hash,只使用前八位
          // 放在build的img 文件夾
          filename: "img/[name]_[hash:8][ext]",
        },
      },
    ],
  },
};

1.13 babel

  • 想要使用 ES6+ 的語(yǔ)法,使用 ts ,開(kāi)發(fā) react,都是離不開(kāi) babel 的
  • 安裝:npm i babel-loader -D
  {
        test: /\.js$/,
        use: ["babel-loader"],
      },
  • babel 是一個(gè)工具鏈,用于舊瀏覽器或者環(huán)境中將 es5 代碼轉(zhuǎn)換為向后兼容版本的 js
    • 語(yǔ)法轉(zhuǎn)換:箭頭函數(shù)
    • 源代碼轉(zhuǎn)換:對(duì)標(biāo)識(shí)符進(jìn)行轉(zhuǎn)化
  • 本身可以作為一個(gè)獨(dú)立的工具,不和webpack等構(gòu)建工具來(lái)單獨(dú)使用
  • 命令行使用,需要安裝
    • @babel/core:babel 的核心代碼,必須安裝
    • @babel/cli:在命令行使用 babel
    • npm i @babel/cli @babel/core -D
  • 安裝插件
    • 轉(zhuǎn)換對(duì)應(yīng)的東西
    • 每個(gè)插件完成對(duì)應(yīng)的功能
  • 單獨(dú)抽取出配置:babel.config.js
module.exports = {
  // plugins: [
  //   "@babel/transform/"
  // ]
  presets: ["@babel/preset-env"],
};

  • 單獨(dú)配置太麻煩了,安裝預(yù)設(shè):npm i @babel/preset-env -D
    • 常見(jiàn)的預(yù)設(shè)
      • env
      • react
      • TypeScript

.vue

  • 安裝 vue :npm i vue開(kāi)發(fā)生產(chǎn)都會(huì)使用
  • 安裝loader:npm i vue-loader -D
   {
        test: /\.vue$/,
        loader:"vue-loader"
      }
  • vue文件中配置對(duì)應(yīng)的 vue 插件:幫助我們解析 css
const { VueLoaderPlugin } = require('vue-loader/dist/index')
const path = require("path");
const { webpack } = require("webpack");
module.exports = {
  // 配置rukou
  entry: "./src/index.js",
  // 配置出口
  output: {
    filename: "bundle.js",
    // 必須是絕對(duì)路徑
    path: path.resolve(__dirname, "./build"),
    // assetModuleFilename: "abc.png",//很少在這配置
  },
  module: {
    // 規(guī)則很多,對(duì)應(yīng)的是數(shù)組類型
    rules: [
      {
        test: /\.vue$/,
        loader:"vue-loader"
      }
    ],
  },
  plugins: [
    new VueLoaderPlugin()
  ]
};

1.14 resolve 模塊解析

  • 用于設(shè)置模塊如何被解析

    • 幫助 webpack 從每個(gè) require/import 語(yǔ)句中,找到需要引入到合適的模塊代碼
  • webpack 能解析三種文件路徑

    • 絕對(duì)路徑
    • 相對(duì)路徑
    • 模塊路徑
      • resolve.modules 中指定的所有目錄檢索模塊:默認(rèn)為 node_modules
      • 設(shè)置別名
  • 解析

    • 文件:imprt utils form './utils/format'js/json

      • 具備擴(kuò)展名,直接打包文件

      • 否則使用 resolve.extentions 自動(dòng)添加擴(kuò)展名

        • 默認(rèn)值是 [‘.wasm’,‘’.mjs’,‘.js’,‘.json’]
      • 可以自己配置 resolve

      • resolve: {
           // 配置后可省略后綴名
           extensions:['.js','.json','.vue','.jsx','.ts','.tsx']
         },
        
    • 文件夾:

      • 在文件夾中根據(jù) resolve.mainFiles 配置選項(xiàng)中指定的文件順序查找
      • 默認(rèn)值是 [‘index’]
      • 再根據(jù) resolve.extentions 來(lái)解析擴(kuò)展名
  • alias

    • 給文件夾配置別名,解決嵌套層次深的問(wèn)題
  resolve: {
    // 省略后綴名
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
    // 給文件夾配置別名
    alias: {
      utils: path.resolve(__dirname, "./src/utils"),
    },
  },

二、webpack 常見(jiàn)的插件和模式

2.1 plugin

  • loader 是用于特定類型的模塊類型進(jìn)行轉(zhuǎn)換
    • .vue .css .png
  • Plugin 作用廣泛的任務(wù),可以做 loader 之外的所有事情
    • 打包優(yōu)化
    • 資源管理
    • 環(huán)境變量注入

2.2 CleanWebpackPlugin

  • 作用:每次修改配置重新打包時(shí)候,不需要手動(dòng)刪除 dist 文件夾
  • 安裝這個(gè)插件:npm i clean-webpack-plugin -D
  • 在插件中進(jìn)行配置
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
  plugins: [new VueLoaderPlugin(),new CleanWebpackPlugin()],
  • 也可以直接在output中將 clear 設(shè)置為true
  output: {
    filename: "bundle.js",
    // 必須是絕對(duì)路徑
    path: path.resolve(__dirname, "./build"),
    // assetModuleFilename: "abc.png",//很少在這配置
    clear: true,
  },

2.3 HtmlWebpackPlugin

  • 在進(jìn)行項(xiàng)目部署的時(shí),必然也是需要有對(duì)應(yīng)的入口文件 index.html,需要對(duì) index.html 進(jìn)行打包處理

  • 安裝這個(gè)插件:npm i html-webpack-plugin -D

  • build 文件夾下面會(huì)自動(dòng)生成 html 文件

  • 在生成過(guò)程會(huì)有一個(gè)模板,在 html-webpack-plugin 的源碼中,有一個(gè) default_index.ejs 模塊

  • 也可以自定義模板

const HtmlWebpackPlugin = require("html-webpack-plugin");
  plugins: [
    new HtmlWebpackPlugin({
      title: "實(shí)時(shí)音頻流可視化",
      // 自己指定模板
      template:'./index.html'
    }),
  ],

2.4 DefinePlugin

  • webpack 中內(nèi)置的插件

  • 全局注入變量

  • 默認(rèn)注入了變量:process.env.NODE_ENV

  • 可以使用 DefinePlugin 中定義的變量

const { DefinePlugin } = require("webpack");
 plugins: [
    new DefinePlugin({
      // 會(huì)當(dāng)成代碼去解析,所以需要加引號(hào)(eval)
      // 前邊是變量,隨便你加不加引號(hào)
      BASE_URL: "'./'",
      lili: "'lili'",
    }),
  ],

2.5 Mode

  • 告訴 webpack目前所處的一個(gè)環(huán)境
  • 默認(rèn)值是 production
  • 可選值有:none| development|production
  • 每一個(gè)模式涉及很多配置
  • 配置: mode:production,

三、Webpack 搭建本地服務(wù)器

3.1 作用

  • 修改代碼后自動(dòng)重新打包并且自動(dòng)刷新
  • 自動(dòng)重新編譯:
    • webpack watch mode:可以自動(dòng)編譯但是不會(huì)自動(dòng)刷新瀏覽器
    • webpack-dev-server(常用)
    • webpack-dev-middleware

3.2 webpack-dev-server

  • 安裝:npm i webpack-dev-server -D
  • 會(huì)搭建一個(gè)本地服務(wù)
  • 會(huì)自動(dòng)進(jìn)行打包,但是不會(huì)生成本地的文件,直接放在內(nèi)存里面,直接給你搭建服務(wù)器,從內(nèi)存中讀取

3.3 模塊熱替換 HMR

  • 在應(yīng)用程序運(yùn)行過(guò)程中,替換、添加、刪除模塊,而無(wú)需重新刷新整個(gè)頁(yè)面
  • 提高開(kāi)發(fā)的速度
    • 不重新加載整個(gè)頁(yè)面
    • 只更新需要變化的內(nèi)容
  • 修改 webpack 的配置,但是還是刷新一整個(gè)頁(yè)面
  devServer: {
    hot:true
  },
  • 需要在 main.js 手動(dòng)指定哪些模塊發(fā)生更新時(shí),進(jìn)行HMR

    • 先判斷是否開(kāi)啟 HMR
    • 再告訴他那個(gè)模塊更新需要發(fā)生替換
    if (module.hot) {
      module.hot.accpet("./utils/math.js", () => {
        console.log("happen hot gengxin");
      })
    }
    
  • 框架已經(jīng)集成好了,不需要手動(dòng)配置

## 3.4 host

  • 設(shè)置主機(jī)地址,默認(rèn)值是 localhost
  • 看 ip 地址:網(wǎng)絡(luò)=》屬性
  • 設(shè)置為 0.0.0.0 都可以看到

3.5 open

  • true / false : 是否自動(dòng)打開(kāi)瀏覽器
  devServer: {
    hot: true,
    // 端口位置
    port: 8888,
    // host設(shè)置主機(jī)地址,默認(rèn)值是 localhost 
    host: '0.0.0.0',
    open: ture,
    // 自動(dòng)把打包的文件進(jìn)行g(shù)zip壓縮
    compress: true 
  },

3.6 區(qū)分開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境

  • 打包適用于生產(chǎn)環(huán)境

  • 創(chuàng)建 config 文件夾

    • webpack.dev.config.js
    • webpack.prod.config.js
  • 使用 serve / build 是不同的兩套配置

  • context 的作用:解析入口和加載器

    • 默認(rèn)路徑是 webpack 的啟動(dòng)路徑(腳本中配置了)
     "build": "webpack --config ./config/webpack.prod.config.js",
        "serve": "webpack serve --config ./config/webpack.dev.config.js"
    
    // 配置入口
    // context:'',
    // 相對(duì)于 context
    entry: "./src/index.js",
    
  • 很多配置是相似的

    • 抽取公共配置:webpack.comm.config.js
      • 哪些是特有的
    • 安裝插件進(jìn)行合并:npm i webpack-merge -D
  • webpack 跑在 node 當(dāng)中,node 支持 commonjs

  • prod

const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.comm.config");
module.exports = merge(commonConfig, {
  mode: production,
  output: {
    clean: true,
  },
});
  • dev
const { merge } = require('webpack-merge')
const commonConfig = require('./webpack.comm.config')
module.exports = merge(commonConfig,{
  mode: development,
  devServer: {
    hot: true,
    // 端口位置
    port: 8888,
    // host設(shè)置主機(jī)地址,默認(rèn)值是 localhost
    host: "0.0.0.0",
    open: ture,
    // 自動(dòng)把打包的文件進(jìn)行g(shù)zip壓縮
    compress: true,
  },
})
  • vue
    • 把所有和 webpack 有關(guān)的放在了 service-cli 里面

四、補(bǔ)充

4.1 命令行

  1. 回到上一層目錄:cd …
  2. 清空命令行:cls
  3. 切換盤(pán)符:f:

4.2 開(kāi)發(fā)

  1. 分享代碼:刪除node_modules發(fā)給同事

五、Node跨域

5.1 跨域

  • 瀏覽器的同源策略:
    • 同源策略是一個(gè)重要的安全策略,它用于限制一個(gè) origin 的文檔或者它加載的腳本如何能與另一個(gè)源的資源進(jìn)行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介
    • 如果兩個(gè) URL 的 protocol、port (en-US) (如果有指定的話) 和 host 都相同的話,則這兩個(gè) URL 是同源
    • 這個(gè)方案也被稱為“協(xié)議/主機(jī)/端口元組”,或者直接是“元組”。
  • 跨域的產(chǎn)生和前端分離的發(fā)展有很大的關(guān)系
    • 早期的服務(wù)器端渲染的時(shí)候,是沒(méi)有跨域的問(wèn)題的
    • 但是隨著前后端的分離,目前前端開(kāi)發(fā)的代碼和服務(wù)器開(kāi)發(fā)的 API 接口往往是分離的,甚至部署在不同的服務(wù)器上的
  • 訪問(wèn)靜態(tài)資源服務(wù)器 和 API 接口服務(wù)器 很有可能不是同一個(gè)服務(wù)器或者不是同一個(gè)端口
  • 瀏覽器發(fā)現(xiàn)靜態(tài)資源和 API 接口(XHR、Fetch)請(qǐng)求不是來(lái)自同一個(gè)地方時(shí)(同源策略),就產(chǎn)生了跨域
  • 靜態(tài)資源服務(wù)器和 API 服務(wù)器(其他資源類同)是同一臺(tái)服務(wù)器時(shí),是沒(méi)有跨域問(wèn)題的

5.2 跨域解決

  • 跨域的解決方案幾乎都和服務(wù)器有關(guān)系,單獨(dú)的前端基本解決不了跨域
  • webpack 配置的本質(zhì)也是在 webpack-server 的服務(wù)器中配置了代理
  • 解決方案
    • 方案一:靜態(tài)資源和 API 服務(wù)器部署在同一個(gè)服務(wù)器中
    • 方案二:服務(wù)器中開(kāi)啟CORS, 即是指跨域資源共享
    • 方案三:node 代理服務(wù)器(webpack中就是它,開(kāi)發(fā)階段使用)
    • 方案四:Nginx 反向代理(真正部署的時(shí)候使用)
  • 不常用:
    • jsonp:現(xiàn)在很少使用了(曾經(jīng)流行過(guò)一段時(shí)間)
    • postMessage
    • websocket:為了解決跨域,所有的接口都變成 socket 通信

5.3 前端請(qǐng)求代碼

  <script>
    // 1.XHR網(wǎng)絡(luò)請(qǐng)求
    const xhr = new XMLHttpRequest()
    xhr.onreadystatechange = function() {
      if (xhr.readyState === XMLHttpRequest.DONE) {
        console.log(JSON.parse(xhr.responseText))
      }
    }
    xhr.open('get', 'http://localhost:8000/users/list')
    xhr.send()


    // 2.fetch網(wǎng)絡(luò)請(qǐng)求
    fetch('http://localhost:8000/users/list').then(async res => {
      const result = await res.json()
      console.log(result)
    })
  </script>

5.4 CORS

  • 跨源資源共享(CORS, Cross-Origin Resource Sharing 跨域資源共享)
    • 它是一種基于 http header 的機(jī)制
    • 該機(jī)制通過(guò)允許服務(wù)器標(biāo)示除了它自己以外的其它源(域、協(xié)議和端口),使得瀏覽器允許這些 origin 訪問(wèn)加載自己的資源。
  • 瀏覽器將 CORS 請(qǐng)求分成兩類:簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求。
  • 只要同時(shí)滿足以下兩大條件,就屬于簡(jiǎn)單請(qǐng)求(不滿足就屬于非簡(jiǎn)單請(qǐng)求)
    • 請(qǐng)求方法是以下是三種方法之一
      • HEAD
      • GET
      • POST
    • HTTP 的頭信息不超出以下幾種字段:
      • Accept
      • Accept-Language
      • Content-Language
      • Last-Event-ID
      • Content-Type:只限于三個(gè)值 application/x-www-form-urlencoded、multipart/form-data、text/plain

六、模塊化原理 - source-map

6.1 source-map

  • 安裝:npm init -y npm i webpack webpack-cli -D

  • mode

    • 看起來(lái)設(shè)置了一個(gè)屬性,實(shí)際上有更多的一個(gè)配置
    • devtool:“eval”
      • 設(shè)置 source-map
  • 代碼通常運(yùn)行在瀏覽器上時(shí),是通過(guò) 打包壓縮 的:

    • 也就是真實(shí)跑在瀏覽器上的代碼,和編寫(xiě)的代碼其實(shí)是有差異的
    • 比如 ES6 的代碼可能被轉(zhuǎn)換成 ES5
    • 比如對(duì)應(yīng)的代碼行號(hào)、列號(hào)在經(jīng)過(guò)編譯后肯定會(huì)不一致
    • 比如代碼進(jìn)行丑化壓縮時(shí),會(huì)將編碼名稱等修改
    • 比如使用了 TypeScript 等方式編寫(xiě)的代碼,最終轉(zhuǎn)換成 JavaScript
  • 但是,當(dāng)代碼報(bào)錯(cuò)需要調(diào)試時(shí)(debug),調(diào)試轉(zhuǎn)換后的代碼是很困難的

  • 但是能保證代碼不出錯(cuò)嗎?不可能。

  • 那么如何可以調(diào)試這種轉(zhuǎn)換后不一致的代碼呢?答案就是 source-map

    • source-map 是從已轉(zhuǎn)換的代碼,映射 到原始的源文件
    • 使瀏覽器可以重構(gòu)原始源并在調(diào)試器中顯示重建的原始源

6.2 使用 source-map

  • 配置: devtool:'source-map',
  • 使用:
    • 第一步:根據(jù)源文件,生成 source-map文件,webpack 在打包時(shí),可以通過(guò)配置生成source-map
    • 第二步:在轉(zhuǎn)換后的代碼,最后添加一個(gè)注釋,它指向 sourcemap
      • //# sourceMappingURL=common.bundle.js.map
      • 瀏覽器會(huì)根據(jù)注釋,查找相應(yīng)的 source-map ,并且根據(jù) source-map 還原代碼,方便進(jìn)行調(diào)試

6.3 分析 source-map

  • 最初 source-map生成的文件大小是原始文件的10倍,第二版減少了約50%,第三版又減少了50%,所以目前一個(gè)133kb的文件,最終的 source-map 的大小大概在300 kb
  • 目前的 source-map 長(zhǎng)什么樣子
    • version:當(dāng)前使用的版本,也就是最新的第三版
    • sources:從哪些文件轉(zhuǎn)換過(guò)來(lái)的source-map和打包的代碼(最初始的文件)
    • names:轉(zhuǎn)換前的變量和屬性名稱(目前使用的是development模式,所以不需要保留轉(zhuǎn)換前的名稱)
    • mappings:source-map用來(lái)和源文件映射的信息(比如位置信息等),一串base64 VLQ(veriable-length quantity可變長(zhǎng)度值)編碼
    • file:打包后的文件(瀏覽器加載的文件)
    • sourceContent:轉(zhuǎn)換前的具體代碼信息(和sources是對(duì)應(yīng)的關(guān)系)
    • sourceRoot:所有的sources相對(duì)的根目錄
  • 幫助進(jìn)行調(diào)試

6.4 生成 source-map

  • 在使用 webpack打包的時(shí)候,生成對(duì)應(yīng)的source-map
    • webpack 提供了非常多的選項(xiàng)(目前是26個(gè)),來(lái)處理 source-map
    • https://webpack.docschina.org/configuration/devtool/
    • 選擇不同的值,生成的 source-map 會(huì)稍微有差異,打包的過(guò)程也會(huì)有性能的差異,可以根據(jù)不同的情況進(jìn)行選擇
  • 下面幾個(gè)值不會(huì)生成 source-map
    • false不使用 source-map,也就是沒(méi)有任何和 source-map 相關(guān)的內(nèi)容。
    • noneproduction 模式下的默認(rèn)值(什么值都不寫(xiě)) ,不生成 source-map。
    • eval:development 模式(開(kāi)發(fā)模式)下的默認(rèn)值,不生成 source-map
      • 但是它會(huì)在 eval 執(zhí)行的代碼中,添加 //# sourceURL=
      • 它會(huì)被瀏覽器在執(zhí)行時(shí)解析,并且在調(diào)試面板中生成對(duì)應(yīng)的一些文件目錄,方便調(diào)試代碼
      • 可以還原源代碼,但是記錄的信息沒(méi)有那么準(zhǔn)確

## 6.5 source-map 值

  • 一般在 production 文件設(shè)置
  • source-map
    • 生成一個(gè)獨(dú)立的 source-map文件,并且在 bundle 文件中有一個(gè)注釋,指向 source-map文件
  • bundle文件中有如下的注釋://# sourceMappingURL=bundle.js.map
    • 開(kāi)發(fā)工具會(huì)根據(jù)這個(gè)注釋找到 source-map文件,并且解析

6.6 設(shè)置

  • production:默認(rèn)為 none,不需要設(shè)置
  • development:默認(rèn)為 eval
  • production:source-map
    • 上線之后再做調(diào)試需要使用

6.7 eval-source-map 值

  • eval-source-map:會(huì)生成 sourcemap,但是 source-map是以 DataUrl 添加到 eval 函數(shù)的后面

6.8 inline-source-map 值

  • inline-source-map:會(huì)生成 sourcemap,但是 source-map是以 DataUrl 添加到 bundle 文件的后面

6.9 cheap-source-map

  • 會(huì)生成 sourcemap,但是會(huì)更加高效一些(cheap低開(kāi)銷),因?yàn)樗鼪](méi)有生成列映射(Column Mapping)
  • 因?yàn)樵陂_(kāi)發(fā)中,只需要行信息通常就可以定位到錯(cuò)誤了
  • 需要用到開(kāi)發(fā)環(huán)境中:mode:development

6.10 cheap-module-source-map

  • 會(huì)生成 sourcemap,類似于 cheap-source-map,但是對(duì)源自 loader 的 sourcemap 處理會(huì)更好

  • 需要用到開(kāi)發(fā)環(huán)境中:mode:development

6.11 hidden-source-map

  • 需要用到生產(chǎn)環(huán)境中:mode:production
  • 會(huì)生成 sourcemap,但是不會(huì)對(duì) source-map文件進(jìn)行引用,瀏覽器沒(méi)有下載
  • 相當(dāng)于刪除了打包文件中對(duì) sourcemap 的引用注釋
  • 手動(dòng)添加
// 被刪除掉的
//# sourceMappingURL=bundle.js.map

6.12 nosources-source-map

  • 會(huì)生成 sourcemap,但是生成的 sourcemap 只有錯(cuò)誤信息的提示,不會(huì)生成源代碼文件
  • 點(diǎn)擊錯(cuò)誤信息,但是點(diǎn)開(kāi)并沒(méi)有

6.13 多個(gè)值的組合

  • 事實(shí)上,webpack 提供的26個(gè)值,是可以進(jìn)行多組合的
  • 組合的規(guī)則如下:
    • inline-|hidden-|eval:三個(gè)值時(shí)三選一
    • nosources:可選值
    • cheap可選值,并且可以跟隨module的值;
  • 那么在開(kāi)發(fā)中,最佳的實(shí)踐
    • 開(kāi)發(fā)階段:推薦使用 source-map 或者 cheap-module-source-map
      • 這分別是vue和react使用的值,可以獲取調(diào)試信息,方便快速開(kāi)發(fā)
    • 測(cè)試階段:推薦使用 source-map 或者 cheap-module-source-map
      • 測(cè)試階段也希望在瀏覽器下看到正確的錯(cuò)誤提示
    • 發(fā)布階段:false、缺省值(不寫(xiě))

七、深入 Babel - polyfill

7.1 Babel - polyfill

  • webpack 底層就是使用 babel 轉(zhuǎn)換代碼

  • Babel是一個(gè)工具鏈,主要用于舊瀏覽器或者環(huán)境中將 ECMAScript 2015+ 代碼轉(zhuǎn)換為向后兼容版本的 JavaScript

  • 包括:語(yǔ)法轉(zhuǎn)換、源代碼轉(zhuǎn)換、Polyfill 實(shí)現(xiàn)目標(biāo)環(huán)境缺少的功能等

7.2 Babel 命令行使用

  • babel 本身可以作為一個(gè)獨(dú)立的工具(和 postcss 一樣),不和 webpack 等構(gòu)建工具配置來(lái)單獨(dú)使用
  • 在命令行使用 babel,需要安裝如下庫(kù):npm install @babel/cli @babel/core
    • 安裝插件:
      • npm i @babel/plugin-transform-block-scoping -D
      • npm i @babel/plugin-transform-arrow-functions -D
  • 使用 babel 來(lái)處理源代碼:npx babel src --out-dir dist
    • src:源文件的目錄 ./src
    • –out-dir:要輸出的文件夾 dist ./build

7.3 Babel 的預(yù)設(shè) preset

  • 如果要轉(zhuǎn)換的內(nèi)容過(guò)多,一個(gè)個(gè)設(shè)置是比較麻煩的,可以使用預(yù)設(shè)(preset)
  • 安裝@babel/preset-env預(yù)設(shè):npm install @babel/preset-env -D
  • 執(zhí)行如下命令:npx babel src --out-dir dist --presets=@babel/preset-env

7.4 Babel 的底層原理

  • babel 將一段代碼(ES6、TypeScript、React)轉(zhuǎn)成另外一段代碼(ES5)

    • 從一種源代碼(原生語(yǔ)言)轉(zhuǎn)換成另一種源代碼(目標(biāo)語(yǔ)言)
    • 就是編譯器的工作,事實(shí)上可以將 babel 看成就是一個(gè)編譯器
  • Babel 編譯器的作用就是將源代碼轉(zhuǎn)換成瀏覽器可以直接識(shí)別的另外一段源代碼

  • Babel 也擁有編譯器的工作流程

    • 解析階段(Parsing)
    • 轉(zhuǎn)換階段(Transformation)
    • 生成階段(Code Generation)
  • 使用:如果沒(méi)有webpack 需要單獨(dú)敲對(duì)應(yīng)的命令:npx babel

    • 結(jié)合 webpack 進(jìn)行使用:npm i webpack webpack-cli -D
  • webpack 對(duì)應(yīng)的是模塊化的內(nèi)容,babel 對(duì)應(yīng)的是es6 轉(zhuǎn)化為es5的內(nèi)容–兩者結(jié)合在一起

7.5 babel-loader

  • 安裝:npm install babel-loader @babel/core -D
    • @babel/core 會(huì)自動(dòng)安裝
  • 必須指定使用的插件才會(huì)生效
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: "babel-loader", //會(huì)自動(dòng)去找對(duì)應(yīng)的 babel 工具
          options: {
            // plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
            presets: ["@babel/preset-env"],
          },
        },
      },
    ],
  },
  • webpack 與 對(duì)應(yīng)的另外一個(gè)工具結(jié)合起來(lái)都是使用對(duì)應(yīng)的 loader

7.6 babel-preset

  • **可以直接給 webpack 提供一個(gè) preset,**webpack會(huì)根據(jù)預(yù)設(shè)來(lái)加載對(duì)應(yīng)的插件列表,并且將其傳遞給 babel
  • 常見(jiàn)的預(yù)設(shè)有三個(gè)
    • env:適配的環(huán)境
    • react:對(duì) react 代碼進(jìn)行轉(zhuǎn)換
    • TypeScript
  • 安裝:npm install @babel/preset-env

7.7 瀏覽器兼容性

  • 兼容性:針對(duì)不同的瀏覽器支持的特性:比如 css 特性、js 語(yǔ)法之間的兼容性

  • 市面上有大量的瀏覽器:

    • 有Chrome、Safari、IE、Edge、Chrome for Android、UC Browser、QQ Browser等等
  • 其實(shí)在很多的腳手架配置中,都能看到類似于這樣的配置信息:

    • 這里的百分之一,就是指市場(chǎng)占有率

    • > 1%
      last 2 versions
      not dead
      
  • 代碼要不要自動(dòng)轉(zhuǎn)換取決于要適配的瀏覽器

  • 瀏覽器市場(chǎng)占有率caniuse

7.8 browserslist 工具

  • 幫助去配置需要兼容的瀏覽器版本
  • Browserslist 是一個(gè)在不同的前端工具之間,共享目標(biāo)瀏覽器和 Node.js 版本的配置:
    • Autoprefixer:自動(dòng)添加瀏覽器前綴
    • Babel
    • postcss-preset-env
    • eslint-plugin-compat
    • stylelint-no-unsupported-browser-features
    • postcss-normalize
    • obsolete-webpack-plugin
  • 條件查詢使用的是 caniuse-lite 的工具,這個(gè)工具的數(shù)據(jù)來(lái)自于 caniuse 的網(wǎng)站上
  • 工程化:很多操作不需要自己來(lái)做,甚至不需要自己來(lái)配置,利用一系列的工具去做這件事情
  • 編寫(xiě)規(guī)則
    • defaults:Browserslist的默認(rèn)瀏覽器(> 0.5%, last 2 versions, Firefox ESR, not dead)
      • not dead:24 個(gè)月之內(nèi)都沒(méi)有官網(wǎng)更新和支持
    • 5%:通過(guò)全局使用情況統(tǒng)計(jì)信息選擇的瀏覽器版本。 >=,<和<=工作過(guò)
      • 5% in US:使用美國(guó)使用情況統(tǒng)計(jì)信息。它接受兩個(gè)字母的國(guó)家/地區(qū)代碼
      • 5% in alt-AS:使用亞洲地區(qū)使用情況統(tǒng)計(jì)信息。有關(guān)所有區(qū)域代碼的列表,請(qǐng)參見(jiàn)caniuse-lite/data/regions
      • 5% in my stats:使用自定義用法數(shù)據(jù)
      • 5% in browserslist-config-mycompany stats:使用 來(lái)自的自定義使用情況數(shù)據(jù)browserslist-config-mycompany/browserslist-stats.json
      • cover 99.5%:提供覆蓋率的最受歡迎的瀏覽器
      • cover 99.5% in US:與上述相同,但國(guó)家/地區(qū)代碼由兩個(gè)字母組成
      • cover 99.5% in my stats:使用自定義用法數(shù)據(jù)
    • dead:24個(gè)月內(nèi)沒(méi)有官方支持或更新的瀏覽器?,F(xiàn)在是IE 10,IE_Mob 11,BlackBerry 10,BlackBerry 7, Samsung 4和OperaMobile 12.1
    • last 2 versions:每個(gè)瀏覽器的最后2個(gè)版本
      • last 2 Chrome versions:最近2個(gè)版本的Chrome瀏覽器
      • ast 2 major versions或last 2 iOS major versions:最近2個(gè)主要版本的所有次要/補(bǔ)丁版本
    • node 10和node 10.4:選擇最新的Node.js10.x.x 或10.4.x版本
      • current node:Browserslist現(xiàn)在使用的 Node.js 版本
      • maintained node versions:所有Node.js 版本,仍由 Node.js Foundation 維護(hù)
    • iOS 7:直接使用iOS瀏覽器版本7
      • Firefox > 20:Firefox的版本高于20 >=,<并且<=也可以使用。它也可以與Node.js一起使用。
      • ie 6-8:選擇一個(gè)包含范圍的版本。
      • Firefox ESR:最新的[Firefox ESR]版本
      • PhantomJS 2.1和PhantomJS 1.9:選擇類似于PhantomJS運(yùn)行時(shí)的Safari版本
    • extends browserslist-config-mycompany:從browserslist-config-mycompanynpm包中查詢 。
    • supports es6-module:支持特定功能的瀏覽器
      • es6-module這是“我可以使用” 頁(yè)面feat的URL上的參數(shù)。有關(guān)所有可用功能的列表,請(qǐng)參見(jiàn) :caniuse-lite/data/features
    • **browserslist config:在Browserslist配置中定義的瀏覽器。**在差異服務(wù)中很有用,可用于修改用戶的配置,例如 browserslist config and supports es6-module。
    • since 2015或last 2 years:自2015年以來(lái)發(fā)布的所有版本(since 2015-03以及since 2015-03-10)
    • unreleased versions或unreleased Chrome versions:Alpha和Beta版本
    • not ie <= 8:排除先前查詢選擇的瀏覽器
  • 命令行使用,自己添加規(guī)則:npx browserslist ">1%, last 2 version, not dead",真實(shí)開(kāi)發(fā)不會(huì)使用

7.9 配置browserslist

  • 查看是否安裝:node_modules
  • 寫(xiě)法一:在package.json中配置: "browserslist":[]
  • 寫(xiě)法二:?jiǎn)为?dú)的一個(gè)配置文件 .browserslistrc 文件,寫(xiě)上對(duì)應(yīng)的規(guī)則

7.10 設(shè)置目標(biāo)瀏覽器 browserslist/ targets

  • 最終打包的 JavaScript 代碼,是需要跑在目標(biāo)瀏覽器上的,那么如何告知 babel 目標(biāo)瀏覽器
    • browserslist 工具
    • target 屬性(一般不使用)
  • 配置的 targets 屬性會(huì)覆蓋 browserslist
  • 但是在開(kāi)發(fā)中,更推薦通過(guò) browserslist來(lái)配置,因?yàn)轭愃朴?postcss工具,也會(huì)使用 browserslist,進(jìn)行統(tǒng)一瀏覽器的適配

7.11 Stage-X 的 preset

  • TC39 的組織
    • TC39是指技術(shù)委員會(huì)(Technical Committee)第 39 號(hào)
    • 它是 ECMA 的一部分,ECMA 是 “ECMAScript” 規(guī)范下的 JavaScript 語(yǔ)言標(biāo)準(zhǔn)化的機(jī)構(gòu)
    • ECMAScript 規(guī)范定義了 JavaScript 如何一步一步的進(jìn)化、發(fā)展
  • TC39 遵循的原則是:分階段加入不同的語(yǔ)言特性,新流程涉及四個(gè)不同的 Stage
    • **Stage 0:**strawman(稻草人,圖紙),任何尚未提交作為正式提案的討論、想法變更或者補(bǔ)充都被認(rèn)為是第 0 階段的"稻草人"
    • **Stage 1:**proposal(提議),提案已經(jīng)被正式化,并期望解決此問(wèn)題,還需要觀察與其他提案的相互影響
    • **Stage 2:**draft(草稿),Stage 2 的提案應(yīng)提供規(guī)范初稿、草稿。此時(shí),語(yǔ)言的實(shí)現(xiàn)者開(kāi)始觀察 runtime 的具體實(shí)現(xiàn)是否合理
    • **Stage 3:**candidate(候補(bǔ)),Stage 3 提案是建議的候選提案。在這個(gè)高級(jí)階段,規(guī)范的編輯人員和評(píng)審人員必須在最終規(guī)范上簽字。Stage 3 的提案不會(huì)有太大的改變,在對(duì)外發(fā)布之前只是修正一些問(wèn)題
    • **Stage 4:**finished(完成),進(jìn)入 Stage 4 的提案將包含在 ECMAScript 的下一個(gè)修訂版中
  • Babel的 Stage-X 設(shè)置,但是從babel7開(kāi)始,已經(jīng)不建議使用了,建議使用preset-env 來(lái)設(shè)置

7.12 Babel 的配置文件

  • babel 配置越多的話,不利于維護(hù),建議創(chuàng)建一個(gè)配置文件
  • 可以將 babel 的配置信息放到一個(gè)獨(dú)立的文件中,babel 提供了兩種配置文件的編寫(xiě):
    • babel.config.json(或者.js,.cjs,.mjs)文件;
    • 喜歡以 js 結(jié)尾
    • .babelrc.json(或者.babelrc,.js,.cjs,.mjs)文件;
  • 它們兩個(gè)有什么區(qū)別呢?目前很多的項(xiàng)目都采用了多包管理的方式(babel本身、element-plus、umi等)
    • .babelrc.json:早期使用較多的配置方式,但是對(duì)于配置Monorepos項(xiàng)目是比較麻煩的;
    • babel.config.json(babel7):可以直接作用于Monorepos項(xiàng)目的子包,更加推薦

7.13 polyfill

  • Polyfill

    • 翻譯:一種用于衣物、床具等的聚酯填充材料, 使這些物品更加溫暖舒適
    • 理解:更像是應(yīng)該填充物(墊片),一個(gè)補(bǔ)丁,可以幫助更好的使用 JavaScript
  • 為什么會(huì)用到 polyfill

    • 比如使用了一些語(yǔ)法特性(例如:Promise, Generator, Symbol 等以及實(shí)例方法(特殊的 api )例如 Array.prototype.includes 等)
    • 但是某些瀏覽器壓根不認(rèn)識(shí)這些特性,必然會(huì)報(bào)錯(cuò)
    • 可以使用 polyfill 來(lái)填充或者說(shuō)打一個(gè)補(bǔ)丁,那么就會(huì)包含該特性了
  • 使用

    • babel7.4.0 之前,可以使用 @babel/polyfill的包,但是該包現(xiàn)在已經(jīng)不推薦使用了

    • babel7.4.0 之后,可以通過(guò)單獨(dú)引入 core-js 和 regenerator-runtime 來(lái)完成 polyfill 的使用,安裝:

      • 開(kāi)發(fā)生產(chǎn)環(huán)境都要使用
      • npm install core-js regenerator-runtime
    • 配置 babel.config.js

      • useBuiltIns:設(shè)置以什么樣的方式來(lái)使用 polyfill
        • false
          • 打包后的文件不使用 polyfill 來(lái)進(jìn)行適配
          • 并且這個(gè)時(shí)候是不需要設(shè)置 corejs 屬性的
        • **usage **(推薦使用)
          • 會(huì)根據(jù)源代碼中出現(xiàn)的語(yǔ)言特性,自動(dòng)檢測(cè)所需要的 polyfill
          • 這樣可以確保最終包里的 polyfill 數(shù)量的最小化,打包的包相對(duì)會(huì)小一些
          • 可以設(shè)置 corejs 屬性來(lái)確定使用的 corejs 的版本
        • entry
          • 如果依賴的某一個(gè)庫(kù)/第三方代碼本身使用了某些 polyfill 的特性,但是因?yàn)槭褂玫氖?usage,所以之后用戶瀏覽器可能會(huì)報(bào)錯(cuò)
          • 所以,如果擔(dān)心出現(xiàn)這種情況,可以使用 entry
          • 并且需要在入口文件(index.js)中添加 `import ‘core-js/stable’; import ‘regenerator-runtime/runtime’
          • 這樣做會(huì)根據(jù) browserslist 目標(biāo)導(dǎo)入所有的 polyfill,但是對(duì)應(yīng)的包也會(huì)變大
      • corejs:設(shè)置 corejs 的版本,目前使用較多的是 3.x 的版本,可以在 package.json 文件中進(jìn)行查看
        • corejs 可以設(shè)置是否對(duì)提議階段的特性進(jìn)行支持
        • 設(shè)置 proposals 屬性為 true
      module.exports = {
        // plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
        presets: [
          [
            "@babel/preset-env",
            {
              // 指定使用版本
              corejs: 3,
              useBuiltIns:false
            },
          ],
        ],
      };
      
      

7.14 React 的 jsx 支持

  • 編寫(xiě) react 代碼時(shí),react 使用的語(yǔ)法是 jsx,jsx 是可以直接使用 babel 來(lái)轉(zhuǎn)換的

  • 安裝 react :npm i react react-dom

  • 安裝 preset :npm install @babel/preset-react -D

  • 掛載到 index.html 上,需要打包 html 文件:npm i html-webpack-plugin -D

  • const HtmlWebpackPlugin = require("HtmlWebpackPlugin ");
      plugins: [
        new HtmlWebpackPlugin({
          template: "./index.html",
        }),
      ],
    
  • module: {
      rules: [
        {
          test: /\.jsx?$/, //x?:0或者1個(gè)
          use: {
            loader: "babel-loader", //會(huì)自動(dòng)去找對(duì)應(yīng)的 babel 工具
            options: {
              // plugins: ["@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping"],
              presets: [["@babel/preset-env", {}], ["@babel/preset-react"]],
            },
          },
        },
      ],
    },
    

7.15 TypeScript 的編譯

  • 可以通過(guò) TypeScript 的 compiler 來(lái)轉(zhuǎn)換成 JavaScript:npm install typescript -D

  • 通過(guò) tsc --init 為 TypeScript 的編譯配置信息編寫(xiě)一個(gè) tsconfig.json 文件

  • 手動(dòng)編譯自己的ts代碼:npx tsc

7.16 使用 ts-loader

  • 安裝:npm install ts-loader -D
  • 在安裝 ts-loader 的時(shí)候會(huì)自動(dòng)安裝 TypeScript 的 compiler
  • 配置
     {
        test: /\.ts$/,
        use:'ts-loader'
      }
  • 通過(guò) npm run build 打包
  • 來(lái)直接編譯 TypeScript,那么只能將 ts 轉(zhuǎn)換成 js
  • 還希望在這個(gè)過(guò)程中添加對(duì)應(yīng)的 polyfill,那么 ts-loader 是無(wú)能為力的
  • 需要借助于 babel 來(lái)完成 polyfill 的填充功能

7.17 使用 babel-loader

  • 一般處理 ts 代碼不會(huì)使用 ts-loader 進(jìn)行處理,會(huì)選擇 babel-loader 進(jìn)行處理
    • ts-loader 需要單獨(dú)安裝 ts-loader
    • 編寫(xiě)代碼過(guò)程也可能用到 polyfill,ts-loader 是沒(méi)有 polyfill 的
  • 使用預(yù)設(shè): npm install @babel/preset-typescript -D
  • 來(lái)直接編譯TypeScript,也可以將 ts 轉(zhuǎn)換成 js,并且可以實(shí)現(xiàn) polyfill 的功能
  • babel-loader 在編譯的過(guò)程中,不會(huì)對(duì)類型錯(cuò)誤進(jìn)行檢測(cè)

7.18 編譯 TypeScript 最佳實(shí)踐

  • 使用 Babel 來(lái)完成代碼的轉(zhuǎn)換,打包代碼

  • 使用 tsc 來(lái)進(jìn)行類型的檢查

    • 在 scripts 中添加了兩個(gè)腳本,用于類型檢查文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-820108.html

      • 執(zhí)行 npm run type-check可以對(duì) ts 代碼的類型進(jìn)行檢測(cè):校驗(yàn)出代碼有沒(méi)有錯(cuò)誤
      • 執(zhí)行 npm run type-check-watch可以實(shí)時(shí)的檢測(cè)類型錯(cuò)誤

到了這里,關(guān)于前端工程化之 webpack <一>的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 前端工程化第一章:webpack基礎(chǔ)(上)

    前端工程化第一章:webpack基礎(chǔ)(上)

    Webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊 打包器 。它是一個(gè)用于 將代碼編譯成瀏覽器可識(shí)別的格式 的工具。 webpack 可以實(shí)現(xiàn)以下的功能: 代碼轉(zhuǎn)換 : TypeScript 編譯成 JavaScript 、 SCSS 、 less 編譯成 CSS 等。 文件優(yōu)化 :壓縮 JavaScript 、 CSS 、 HTML 代碼, 壓縮合并圖片

    2024年02月17日
    瀏覽(25)
  • 【前端工程化面試題目】webpack 的熱更新原理

    【前端工程化面試題目】webpack 的熱更新原理

    可以在順便學(xué)習(xí)一下 vite 的熱更新原理,請(qǐng)參考這篇文章。 首先有幾個(gè)知識(shí)點(diǎn)需要明確 熱更新是針對(duì)開(kāi)發(fā)過(guò)程中的開(kāi)發(fā)服務(wù)器的,也就是 webpack-dev-server webpack 的熱更新不需要額外的插件,但是需要在配置文件中 devServer 屬性中配置 hot: true,需要安裝?webpack-dev-server 這個(gè)

    2024年02月19日
    瀏覽(95)
  • 【前端工程化面試題】說(shuō)一下 webpack 的構(gòu)建流程

    類似問(wèn)題是,說(shuō)一下 vite 的構(gòu)建流程,參考這篇文章。 初始化流程 從配置文件和shell 語(yǔ)句中讀取合并參數(shù),初始化需要使用的插件和執(zhí)行環(huán)境所需要的參數(shù) 配置文件默認(rèn)是 webpack.config.js 編譯構(gòu)建流程 解析入口模塊,從入口模塊開(kāi)始串行調(diào)用對(duì)應(yīng)的loader 去翻譯文件內(nèi)容,依

    2024年02月20日
    瀏覽(95)
  • 前端工程化第三章:webpack5基礎(chǔ)(下)

    前端工程化第三章:webpack5基礎(chǔ)(下)

    TypeScript 是一種靜態(tài)類型的編程語(yǔ)言,是 JavaScript 的一個(gè)超集。它由 微軟開(kāi)發(fā),提供了許多 JavaScript 不支持的功能,比如 類型檢查 、 接口和類 。 ts-loader 是 Webpack 中的一個(gè)加載器,用于將 TypeScript 代碼轉(zhuǎn)換成 JavaScript 代碼。它是基于 typescript 編譯器實(shí)現(xiàn)的,支持所有 TypeS

    2024年02月16日
    瀏覽(22)
  • 前端工程化第一章:webpack5基礎(chǔ)(上)

    前端工程化第一章:webpack5基礎(chǔ)(上)

    Webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊 打包器 。它是一個(gè)用于 將代碼編譯成瀏覽器可識(shí)別的格式 的工具。 webpack 可以實(shí)現(xiàn)以下的功能: 代碼轉(zhuǎn)換 : TypeScript 編譯成 JavaScript 、 SCSS 、 less 編譯成 CSS 等。 文件優(yōu)化 :壓縮 JavaScript 、 CSS 、 HTML 代碼, 壓縮合并圖片

    2024年02月16日
    瀏覽(32)
  • Vue3學(xué)習(xí)-01_前端工程化與webpack

    最近在學(xué)習(xí)Vue知識(shí),參照的教程是黑馬程序員官網(wǎng)提供的免費(fèi)前端教程,這里記錄一下自己的學(xué)習(xí)筆記以及遇到的相關(guān)問(wèn)題。 前端工程化指的是:在企業(yè)級(jí)的前端項(xiàng)目開(kāi)發(fā)中,把前端開(kāi)發(fā)所需的工具、技術(shù)、流程、經(jīng)驗(yàn)等進(jìn)行規(guī)范化、標(biāo)準(zhǔn)化。最終落實(shí)到細(xì)節(jié)上,就是實(shí)現(xiàn)前

    2024年02月13日
    瀏覽(29)
  • 【前端工程化面試題】如何優(yōu)化提高 webpack 的構(gòu)建速度

    【前端工程化面試題】如何優(yōu)化提高 webpack 的構(gòu)建速度

    使用最新版本的 Webpack 和相關(guān)插件 : 每個(gè)新版本的 Webpack 都會(huì)帶來(lái)性能方面的改進(jìn)和優(yōu)化,因此始終確保你在使用最新版本。同時(shí),更新你的相關(guān)插件也是同樣重要的。 使用DllPlugin動(dòng)態(tài)鏈接庫(kù): 使用DllPlugin和DllReferencePlugin來(lái)將第三方庫(kù)的代碼進(jìn)行預(yù)打包,減少構(gòu)建時(shí)間。這個(gè)

    2024年02月19日
    瀏覽(95)
  • 前端工程化之:webpack4-1(babel的安裝和使用)

    前端工程化之:webpack4-1(babel的安裝和使用)

    官網(wǎng):https://babeljs.io/ 民間中文網(wǎng):https://www.babeljs.cn/ ?babel一詞來(lái)自于希伯來(lái)語(yǔ),直譯為巴別塔。 巴別塔象征的統(tǒng)一的國(guó)度、統(tǒng)一的語(yǔ)言 而今天的 JS 世界缺少一座巴別塔,不同版本的瀏覽器能識(shí)別的 ES 標(biāo)準(zhǔn)并不相同,就導(dǎo)致了開(kāi)發(fā)者面對(duì)不同版本的瀏覽器要使用不同的語(yǔ)言

    2024年02月21日
    瀏覽(68)
  • 【前端工程化面試題】webpack的module、bundle、chunk分別指的是什么?

    首先從語(yǔ)法方面 在配置文件中有 module 這個(gè)配置項(xiàng),里面有 rules 選項(xiàng)用來(lái)配置各種 loader,還有其他各種選項(xiàng),參考官網(wǎng)。 bundle 和?chunk 在配置文件中是沒(méi)有這個(gè)選項(xiàng)的,但是會(huì)出現(xiàn)在配置的值中。 module 模塊 指單個(gè)文件,可以是 js、css、圖片等, 每個(gè)文件都是一個(gè)獨(dú)立的模

    2024年02月19日
    瀏覽(89)
  • 【前端工程化面試題】webpack proxy的工作原理,為什么能解決跨域問(wèn)題

    【前端工程化面試題】webpack proxy的工作原理,為什么能解決跨域問(wèn)題

    在 webpack 的配置文件 webpack.config.js 中有一個(gè)配置項(xiàng) devServer 里面有一個(gè)屬性是 proxy,這里面可以配置代理服務(wù)器,解決跨域問(wèn)題,請(qǐng)參考官網(wǎng)。 一般來(lái)說(shuō) webpack 的代理就是說(shuō)的開(kāi)發(fā)服務(wù)器 webpack-dev-server。 其實(shí)不光是 webpack 其他的打包工具比如是 vite,也有代理的功能,也是

    2024年02月21日
    瀏覽(95)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包