国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

webpack4介紹與總結(jié)

yanbingyun1990 / 3210人閱讀

摘要:隨著承擔(dān)地職責(zé)越來(lái)越大,模塊化開(kāi)發(fā)的需求越來(lái)越急迫。我們可以把當(dāng)成是模塊化標(biāo)準(zhǔn)的實(shí)現(xiàn)方案,但的功能不僅限于此。支持多種模塊使用方式,包括的。下面介紹一下在工程中常用的。最后一個(gè)的輸出就是我們最終要的結(jié)果。在文件有值的情況下,是必要的。

由于web應(yīng)用擴(kuò)展地得極其迅猛,前端技術(shù)也是日新月異,前端的苦不是有多難學(xué),而是我剛學(xué)完,這東西就被淘汰了(手動(dòng)哭臉)。框架方面我們有vue、react、angular,我們需要寫(xiě)vue單文件,也需要寫(xiě)jsx語(yǔ)法;js方面我們有Typescript、es6(7、8、9),現(xiàn)在是每年一個(gè)小版本的迭代,語(yǔ)法也是在不斷更新和淘汰;模塊方面我們有es6的modlue、CommonJS、AMD;css方面我們有sass、less、postcss。新技術(shù)層出不窮,瀏覽器實(shí)現(xiàn)跟不上,還要考慮到瀏覽器兼容性問(wèn)題,是一個(gè)令人頭大的問(wèn)題。但是webpack可以輕松幫我們解決這些問(wèn)題,我們可以在webpack的世界中放心地使用上述提到的技術(shù),以更方便、舒服的方式完成我們開(kāi)發(fā)。

webpack是什么

At its core, webpack is a static module bundler for modern JavaScript applications. 這是官網(wǎng)的定義,webpack就是一個(gè)靜態(tài)模塊的打包工具。webpack可以將工程中的靜態(tài)資源根據(jù)我們聲明的依賴關(guān)系,打包出最后的正常運(yùn)行的輸出文件。官網(wǎng)顯示的這幅圖很形象地描述了這個(gè)過(guò)程:

在webpack中,所有的靜態(tài)資源都可以被處理為一個(gè)模塊,包括js、圖片、css、字體。模塊化是前端開(kāi)發(fā)的主要模式,模塊化的好處有很多,我想到的有以下3種:

更輕松地拆分代碼邏輯,對(duì)于大型工程尤其重要

更容易地去管理變量,模塊會(huì)自動(dòng)生成一個(gè)局部變量環(huán)境,減少全局變量的污染

顯示地聲明依賴關(guān)系,想想之前在head中引入很多script標(biāo)簽,由于script順序錯(cuò)誤而引起的bug

在es6之前,原生js是不支持模塊化開(kāi)發(fā)。因?yàn)閖s設(shè)計(jì)之初,只是為了實(shí)現(xiàn)表單驗(yàn)證等簡(jiǎn)單的交互,并沒(méi)有考慮到要用js來(lái)寫(xiě)大型的web應(yīng)用。隨著js承擔(dān)地職責(zé)越來(lái)越大,模塊化開(kāi)發(fā)的需求越來(lái)越急迫。于是,js社區(qū)誕生出了CommonJS、AMD這樣的js模塊化標(biāo)準(zhǔn),隨后在es6中,也終于加入了module的原生支持。現(xiàn)在最新版本的各大瀏覽器均已實(shí)現(xiàn)了對(duì)es6的module語(yǔ)法支持,但也僅限于最新的幾個(gè)版本,詳情可以查看一下can i ues。我們可以把webpack當(dāng)成是模塊化標(biāo)準(zhǔn)的實(shí)現(xiàn)方案,但webpack的功能不僅限于此。

webpack支持多種模塊使用方式,包括es6的module、CommonJS、AMD。推薦使用es6的module語(yǔ)法,一方面是因?yàn)樗菢?biāo)準(zhǔn),是以后模塊化語(yǔ)法的主要使用方式;另一方面,是因?yàn)樗庆o態(tài)的,webpack可以依靠靜態(tài)分析,做一些優(yōu)化,比如Treeshaking。webpack自帶js模塊處理功能,其他類(lèi)型的靜態(tài)資源我們需要通過(guò)配置相應(yīng)的loader去處理。

概念和配置

webpack中最重要的概念有以下幾個(gè):

Entry, 工程的入口文件配置

Output, 打包的輸出的文件配置

Chunk, webpack處理和輸出的包

Loaders, 加載器,用于處理各種不同類(lèi)型的模塊,可擴(kuò)展

Plugins, 插件,在webpack打包過(guò)程中不同時(shí)機(jī)執(zhí)行一些任務(wù),比如清除打包目錄、復(fù)制靜態(tài)文件、抽取css文件

Mode, 區(qū)分開(kāi)發(fā)環(huán)境和生成環(huán)境

webpack一般根據(jù)配置文件去執(zhí)行打包任務(wù),我們創(chuàng)建一個(gè)webpack.config.js文件來(lái)編寫(xiě)我們的打包配置。

Entry

Entry,顧名思義就是工程的入口文件,Entry的配置寫(xiě)法有三種:

對(duì)象,可配置多入口,可配置chunk名,靈活可擴(kuò)展,最常用,一個(gè)屬性就是一個(gè)entry chunk

module.exports = {
  entry: {
    app: "./src/app.js",
    vendors: "./src/vendors.js"
  }
};

字符串, 最簡(jiǎn)單直接方式,單入口,chunk名默認(rèn)為main

module.exports = {
  entry: "./path/to/my/entry/file.js"
};

數(shù)組, 多入口,將多個(gè)入口文件打包為一個(gè)chunk,chunk名默認(rèn)為main

module.exports = {
  entry: ["./path/to/my/entry/file.js", "./path/to/my/entry/file1.js"]
};

入口一般用對(duì)象寫(xiě)法即可,其他兩種寫(xiě)法的可忽略。

Output

Output用于配置打包輸出的文件,包括輸出文件的文件名、輸出路徑、靜態(tài)資源地址,這里列出最常用的4種:

module.exports = {
  entry: {
    app: "./src/app.js",
    search: "./src/search.js"
  },
  output: {
    filename: "js/[name].js",
    chunkFilename: "js/[name].js",
    path: __dirname + "/dist",
    publicPath: "http://cdn.example.com/assets/[hash]/"
  }
};

配置項(xiàng)如下:

filename: 配置輸出文件名,可添加路徑配置(例子中js/),可使用占位符,占位符有以下5種:

name: chunk名,在該例子中就是app和search

hash: 模塊標(biāo)識(shí)符的hash值,跟工程內(nèi)容相關(guān)

chunkhash: chunk內(nèi)容的hash值,只和當(dāng)前chunk內(nèi)容相關(guān),可用于緩存設(shè)置

id: 模塊標(biāo)識(shí)符

query:模塊查詢參數(shù),取文件名中?后面的內(nèi)容

path: 文件的輸出路徑,必須是絕對(duì)地址

publicPath: 用于設(shè)置打包過(guò)程中產(chǎn)生的靜態(tài)文件的最終引用地址,靜態(tài)文件的最終引用地址為output.publicPath + output.filename,很多時(shí)候,你的靜態(tài)文件放置在CDN上,通過(guò)publicPath就可以很方便地設(shè)置。如果你的靜態(tài)引用地址在運(yùn)行時(shí)才能確定,可以在入口文件中設(shè)置__webpack_public_path__ 來(lái)決定publicPath的值:

__webpack_public_path__ = myRuntimePublicPath;

// rest of your application entry

chunkFilename: 用于設(shè)置非entry入口的chunk的輸出文件名,非entry入口的chunk一般在動(dòng)態(tài)引入和CommonsChunkPlugin中產(chǎn)生,這是一個(gè)Plugin,用于抽取公共代碼或者進(jìn)行代碼分割等操作,該plugin已經(jīng)在webpack4中廢除,由webpac4內(nèi)置的optimization.splitChunks替代,后面會(huì)講到

output還有其他很多配置,這4個(gè)是常用配置。

Loaders

Loaders可以理解為不同類(lèi)型模塊的處理器,將這些類(lèi)型的模塊處理為瀏覽器可運(yùn)行和識(shí)別的代碼。比如babel-loader將es6以上代碼轉(zhuǎn)換為es5代碼;sass-loader將sass代碼解析為css代碼;url-loader和file-loader可以將圖片、字體等靜態(tài)文件解析為base64碼或者靜態(tài)文件地址。Loaders給我們提供了處理模塊的入口,在里面可以使用全部的js功能,從而使webpack具有了強(qiáng)大而靈活的能力。webpack及webpack社區(qū)提供了功能強(qiáng)大的loader供開(kāi)發(fā)者使用,你也可以自己編寫(xiě)loader。下面介紹一下在工程中常用的loader。

js Loaders
babel-loader

使用babel將ES2015+的代碼轉(zhuǎn)碼為ES5的代碼,babel的具體配置可參考babel官網(wǎng)

modlue: {
    rules: [
        {
             test: /.js$/,
             exclude: /(node_modules|bower_components)/,
             use: "babel-loader
        }
    ]
}

exclude表示不處理的目錄,一般node_modules中的第三方j(luò)s文件不在我們的處理范圍內(nèi)。

script-loader

該loader使對(duì)應(yīng)的js文件在全局環(huán)境中運(yùn)行一次。比如我們?cè)诠こ讨惺褂昧薺query的插件,需要全局暴露$,我們就需要讓jquery文件在全局環(huán)境中運(yùn)行,以便讓它把$掛載到全局變量中,效果和在瀏覽器中加script標(biāo)簽一樣。

import "jquery";

module: {
    rules: [
        {
        test: /jquery$/,
        use: [ "script-loader" ]
        }
    ]
}
css Loaders

style-loader:將css模塊以style標(biāo)簽的形式加入到html中

css-loader:主要用來(lái)解析css中的靜態(tài)資源,將@import和url()解析為import/require(),解析出的除css以外的靜態(tài)資源,一般交給url-loader和file-loader去處理

postcss-loader:可以對(duì)css進(jìn)行各種處理,功能強(qiáng)大,比如自動(dòng)添加css前綴,也可自定義插件

sass-loader/less-loader:將sass/less代碼轉(zhuǎn)換為css

解析一個(gè)sass文件,并不只需要一個(gè)loader,它需要多個(gè)loader串行處理,webpack可以配置多個(gè)loader串行處理:

module: {
    rules: [
        {
        test: /.sass$/,
        use: [ "style-loader", "css-loader", "postcss-loader", "sass-loader" ]
        }
    ]
}

我們可以將use配置為一個(gè)數(shù)組,loader從右往左依次執(zhí)行,且前一個(gè)loader的結(jié)果是下一個(gè)loader的輸入。最后一個(gè)loader的輸出就是我們最終要的結(jié)果。一個(gè)sass文件首先經(jīng)過(guò)sass-loader處理,變成css文件,又經(jīng)過(guò)postcss-loader處理,添加瀏覽器前綴等功能,接著交給css-loader去解析css文件引用的靜態(tài)變量,最后由style-loaderscript標(biāo)簽的形式加入到html中。

Files Loaders

url-loaderfile-loader是一對(duì)用來(lái)處理圖片、svg、視頻、字體等靜態(tài)資源文件的loader。一般體積比較小的資源交給url-loader處理,編碼為base64字符串,直接嵌入js文件中。體積較大的文件由file-loader處理,直接釋放為了一個(gè)輸出文件。

{
    test: /.(png|jpe?g|gif|svg)(?.*)?$/,
    loader: "url-loader",
    options: {
        limit: 10000,
        name: "img/[name].[hash:7].[ext]"
    }
},

一般只配置url-loader即可,在資源超過(guò)limit的時(shí)候,url-loader會(huì)將資源自動(dòng)交給file-loader處理,并將options內(nèi)容也傳遞給file-loader。

Plugins

loaders用來(lái)轉(zhuǎn)換某種特定類(lèi)型的module,plugins則用來(lái)在一些合適的時(shí)機(jī)執(zhí)行一些特定的任務(wù),比如代碼分割、靜態(tài)資源處理、環(huán)境變量的注入、將所有css的module抽取為單個(gè)文件等。webpack自身也是用插件系統(tǒng)構(gòu)建起來(lái)的。插件的目的是做任何loaders做不了的事情。

HtmlWebpackPlugin

HtmlWebpackPlugin插件可以用來(lái)生成包含你所有打包文件(js和css)的html文件,特別是你在打包文件名配置了hash,就不得不用這個(gè)插件了。

module.exports = {
  plugins: [
      new HtmlWebpackPlugin({
          template: path.resolve(__dirname, "src/index.html"),  
          filename: "static/index.[hash].html",  
          inject: true, 
          minify: false, 
          chunks: ["app", "vendor"] 
      })
  ]
};

template: HtmlWebpackPlugin生成html文件的模板,如果簡(jiǎn)單的話可以直接通過(guò)其他配置項(xiàng)生成,不必多帶帶提供一個(gè)html文件模板,詳情可參考HtmlWebpackPlugin

filename: 輸出的html文件名,規(guī)則和output的filename相同

inject: 是否注入打包的文件,包括js和通過(guò)MiniCssExtractPlugin打包輸出的css文件,默認(rèn)為true

minify: 是否壓縮

chunks: 只注入某些特定chunk的輸出文件,在多文件場(chǎng)景下比較有用

MiniCssExtractPlugin

MiniCssExtractPlugin將一個(gè)chunk中的css抽取為一個(gè)多帶帶的css文件,如果chunk中不包含css,則不生成文件。且支持按需加載和sourceMap。webpack4新增插件,在webpack4之前是使用ExtractTextWebpackPlugin來(lái)做這件事。官方文檔總結(jié)了MiniCssExtractPlugin相對(duì)ExtractTextWebpackPlugin的四個(gè)優(yōu)勢(shì):

按需異步加載

沒(méi)有重復(fù)編譯(性能)

使用更簡(jiǎn)單

專(zhuān)門(mén)為css設(shè)計(jì)

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== "production"

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: "[name].css",
      chunkFilename: "[id].css"
    })
  ],
  module: {
    rules: [
      {
        test: /.css$/,
        use: [
          devMode ? "style-loader" : {  // MiniCssExtractPlugin目前還沒(méi)有HMR功能,所以最好只在生成環(huán)境使用
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: "../" // 可多帶帶配置publicPath,默認(rèn)采用output中的publicPath
            }
          },
          "css-loader"
        ]
      }
    ]
  }
}
CopyWebpackPlugin

CopyWebpackPlugin用來(lái)處理靜態(tài)文件,可以將文件或者文件夾原封不動(dòng)地移動(dòng)到打包目錄。

const CopyWebpackPlugin = require("copy-webpack-plugin")

const config = {
  plugins: [
    new CopyWebpackPlugin([
        { from: "source", to: "dest" },
        { from: "source", to: "dest", toType: "dir|file|template" }, // 手動(dòng)設(shè)置to的類(lèi)型,比如設(shè)置成dir,即使to設(shè)置為a.js,最后也會(huì)生成a.js文件夾
        { from: "source", to: "dest", context: "/app" }, // 基準(zhǔn)目錄,from相對(duì)于context解析
        { from: "source", to: "dest", ignore: ["*.js"] }, // ignore, 忽略匹配的文件
        "source" // 只有from,to默認(rèn)為output的path
     ], {
         context: "/app", // 同上
         ignore: ["*.js"], // 同上
     })
  ]
}
CleanWebpackPlugin

CleanWebpackPlugin用來(lái)清除打包目錄,主要用于每次重新生成的時(shí)候,清除殘留文件。在文件有hash值的情況下,是必要的。

const CleanWebpackPlugin = require("clean-webpack-plugin");
const config = {
  plugins: [
    new CleanWebpackPlugin(["dist", "bulid/*.js"], {
        watch: false, // 是否在--watch模式下也清除files然后重新編譯,默認(rèn)為false
        exclude: [ "files", "svg", "css" ] // 不刪除的子目錄和文件
    }),
  ]
}
DefinePlugin

DefinePlugin用來(lái)定義webpack編譯期間的全局變量。我們可以根據(jù)這些變量,來(lái)做不同的動(dòng)作。最典型的就是可以區(qū)分開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境,比如在開(kāi)發(fā)環(huán)境打印各種警告、錯(cuò)誤,在生產(chǎn)環(huán)境去掉這些跟業(yè)務(wù)無(wú)關(guān)的代碼。

DefinePlugin的參數(shù)是一個(gè)對(duì)象,鍵名是一個(gè)標(biāo)識(shí)符,或者用.隔開(kāi)的多級(jí)標(biāo)識(shí)符,參數(shù)遵循以下規(guī)則

如果參數(shù)值是一個(gè)字符串,則被當(dāng)做代碼塊

如果參數(shù)值不是字符串,則會(huì)自動(dòng)轉(zhuǎn)換為字符串

如果參數(shù)值是一個(gè)對(duì)象,則對(duì)象的每個(gè)值都按照上述規(guī)則被定義為全局變量

如果鍵名前面有typeof,則只是定義typeof的調(diào)用

new webpack.DefinePlugin({
 "process.env.NODE_ENV": JSON.stringify("production"),
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify("5fa3b9"),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: "1+1",
  "typeof window": JSON.stringify("object")
});

index.js

console.log("PRODUCTION", PRODUCTION);
console.log("VERSION", VERSION);
console.log("BROWSER_SUPPORTS_HTML5", BROWSER_SUPPORTS_HTML5);
console.log("TWO", TWO);
console.log("Object", typeof window);

被編譯為

console.log("PRODUCTION", true);
console.log("VERSION", "5fa3b9");
console.log("BROWSER_SUPPORTS_HTML5", true);
console.log("TWO", 1+1);
console.log("Object",  false ? undefined : _typeof(window));    // 不太明白

DefinePlugin的原理很簡(jiǎn)單,只是在編譯過(guò)程中遇到這些定義好的鍵名,就用鍵值做簡(jiǎn)單的文本替換。所以,你如果想給全局變量賦一個(gè)字符串,需要這樣寫(xiě)""production"",一般使用JSON.stringify來(lái)轉(zhuǎn)一下。

Mode

webpack4新增了mode配置。webpack會(huì)根據(jù)mode值自動(dòng)幫你做一個(gè)不同的優(yōu)化:

production(默認(rèn)值)

DefinePlugin 中將process.env.NODE_ENV設(shè)置為production

默認(rèn)啟用了如下插件:FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin and UglifyJsPlugin

development:

DefinePlugin 中將process.env.NODE_ENV設(shè)置為development

默認(rèn)啟用了如下插件:NamedChunksPlugin , NamedModulesPlugin

none: 什么都不做

mode的兩種使用方式

配置:

module.exports = {
  mode: "production"
};

命令行:

webpack --mode=production
代碼分割

代碼分割可以把代碼按照一定的邏輯分割,用來(lái)做按需加載或者并行加載,以減少加載時(shí)間。在webpack中,主要有以下3中方式,實(shí)現(xiàn)代碼分割:

Entry Points: 手動(dòng)在entry入口配置處配置多個(gè)入口

SplitChunks: webpack4默認(rèn)帶這個(gè)優(yōu)化插件,用于抽取不同chunk的公共部分,或者直接代碼分割

Dynamic Imports: 動(dòng)態(tài)加載,在函數(shù)中使用import()語(yǔ)法,webpack使用SplitChunksimport()加載的module分割為一個(gè)多帶帶的chunk,并在函數(shù)執(zhí)行時(shí)加載該chunk對(duì)應(yīng)的js文件。

第一種沒(méi)什么好說(shuō)的,主要說(shuō)一下后兩種。

SplitChunks

在webpack4之前的版本,都是使用CommonsChunkPlugin來(lái)抽取公共chunk,在webpack4中廢棄了CommonsChunkPlugin,轉(zhuǎn)而支持內(nèi)置的optimization.splitChunks

splitChunks默認(rèn)只對(duì)按需加載的chunk起作用,會(huì)自動(dòng)將import()引入的module分割為多帶帶chunk,但是需要滿足以下條件:

新chunk中的模塊被共享或者來(lái)自node_modules

新chunk必須大于30kb(before min+gz)

按需加載的chunks并行加載的數(shù)量要小于等于5

入口文件的并行加載的請(qǐng)求應(yīng)該小于等于3

在執(zhí)行后兩個(gè)原則的時(shí)候,體積大的chunk被優(yōu)先生成。

splitChunks的默認(rèn)配置如下,我們可以看出正好是和上面4個(gè)條件對(duì)應(yīng)的:

module.exports = {
  optimization: {
    splitChunks: {
      chunks: "async",
      minSize: 30000, // chunk只有超過(guò)這個(gè)大小才會(huì)被分割
      maxSize: 0, // 大于這個(gè)體積的chunk會(huì)被自動(dòng)分割為更小的chunk
      minChunks: 1, // 一個(gè)模塊被共享的chunk數(shù)量大于minChunks時(shí),才會(huì)被分割出來(lái)
      maxAsyncRequests: 5, // 按需加載最大的并行數(shù)
      maxInitialRequests: 3, // 初始加載最大的并行數(shù)
      automaticNameDelimiter: "~", // name為true時(shí),新chunk的文件名由cacheGroups的key加上chunks屬性的一些信息生成,automaticNameDelimiter是分隔符
      name: true,
      cacheGroups: {  // 配置拆分規(guī)則,會(huì)繼承splitChunks所有的配置項(xiàng),所有splitChunks配置項(xiàng)都可以在這里重寫(xiě)覆蓋,test、prioprity、reuseExistingChunk是cacheGroups獨(dú)有的屬性
        vendors: {
          test: /[/]node_modules[/]/, // 模塊匹配規(guī)則,可以是正則表達(dá)式或者函數(shù),不寫(xiě)默認(rèn)選擇所有模塊
          priority: -10 // 優(yōu)先級(jí),當(dāng)同一個(gè)模塊同時(shí)包含在不同cacheGroup中,該模塊將被劃分到優(yōu)先級(jí)高的組中
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true  // 如果該chunk包含的modules都已經(jīng)另一個(gè)被分割的chunk中存在,那么直接引用已存在的chunk,不會(huì)再重新產(chǎn)生一個(gè)
        }
      }
    }
  }
};
chunks

splitChunks的chunks屬性表示作用的chunk范圍。chunks可以是一個(gè)函數(shù),完全由開(kāi)發(fā)者控制;也可以是一個(gè)字符串,字符串一共有3個(gè)值:

initial,表示只作用于入口chunk

async,表示只作用于動(dòng)態(tài)引入的異步chunk

all,所有chunk

name

name屬性表示最后生成chunk的文件名,有以下3中類(lèi)型取值:

boolean,設(shè)置為true,則會(huì)根據(jù)cacheGroup的key和chunks屬性的信息自動(dòng)生成

string,如果設(shè)置在splitChunks下,那所有chunk設(shè)置為相同的名稱,這會(huì)造成不同的chunk合成為一個(gè)chunk,當(dāng)然你可以設(shè)置在cacheGroup

function,完全由開(kāi)發(fā)者控制

Tree Shaking

Tree Shaking這次詞很形象,搖樹(shù),把爛掉的樹(shù)葉搖下來(lái)。我們工程中的爛樹(shù)葉就是那些我們導(dǎo)出了,但是沒(méi)有用到的代碼,Tree Shaking可以幫助我們?nèi)コ裏o(wú)效代碼,減小打包體積,有其在大工程中,效果明顯。

Tree Shaking的使用三部曲:

靜態(tài)的模塊語(yǔ)法

使用Tree Shaking的第一個(gè)前提條件就是必須使用ES2015的模塊語(yǔ)法,import,export。因?yàn)镋S2015的模塊語(yǔ)法是靜態(tài)加載的,而CommonJS和AMD都是動(dòng)態(tài)加載靜態(tài)加載是指在編譯階段你就能確定導(dǎo)出和加載的內(nèi)容。ES2015在語(yǔ)法上規(guī)定:你只能在頂層模塊作用域進(jìn)行導(dǎo)入導(dǎo)出操作,不允許在條件語(yǔ)句中導(dǎo)入導(dǎo)出,也不允許導(dǎo)入和導(dǎo)出的內(nèi)容有變量。這意味著你只分析源碼就可以確定導(dǎo)入和導(dǎo)出的內(nèi)容,而不是等到運(yùn)行時(shí)才能確定。比如說(shuō)下面CommonJS的語(yǔ)法,在ES6中就是不能使用的:

var my_lib;
if (Math.random()) {
    my_lib = require("foo");
} else {
    my_lib = require("bar");
}

你只有在運(yùn)行的時(shí)候,才知道到底加載是的foo還是bar。ES6強(qiáng)制模塊語(yǔ)法靜態(tài)化,失去了一定的靈活性,但是帶來(lái)了更多的好處,其中之一就是我們可以通過(guò)靜態(tài)分析去實(shí)現(xiàn)Tree Shaking。

sideEffects

在完全的Es6模塊世界中,代碼是沒(méi)有副作用的,但是現(xiàn)在我們可能用到的各種地方庫(kù)會(huì)有副作用。副作用是指代碼除了導(dǎo)入和導(dǎo)出,還做了一些其他影響了其他代碼的行為,比如定義了全局變量。最典型的例子就是polyfills,比如Promise的polyfills就定義了Promise全局變量。這時(shí)候如果我們分析到Promise有未使用的導(dǎo)出代碼,則不能刪除,否則可能會(huì)影響Promise的使用。哪些是有副作用的代碼,需要你識(shí)別,并且告訴webpack,方式就是通過(guò)設(shè)置sideEffects,可以設(shè)置在package.json文件中,也可以設(shè)置的module.rules中。

{
  "name": "your-project",
  "sideEffects": [
    "./src/some-side-effectful-file.js",
    "*.css"
  ]
}
UglifyJSPlugin

webpack會(huì)通過(guò)靜態(tài)分析找到冗余代碼,并打上標(biāo)記,我們看一下官網(wǎng)例子:

math.js

export function square(x) {
  return x * x;
}

export function cube(x) {
  return x * x * x;
}

index.js

 import { cube } from "./math.js";

  function component() {
   var element = document.createElement("pre");

   element.innerHTML = [
     "Hello webpack!",
     "5 cubed is equal to " + cube(5)
   ].join("

");

    return element;
  }

  document.body.appendChild(component());

development模式下打包,內(nèi)容如下:

/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
  "use strict";
  /* unused harmony export square */
  /* harmony export (immutable) */ __webpack_exports__["a"] = cube;
  function square(x) {
    return x * x;
  }

  function cube(x) {
    return x * x * x;
  }
});

我們可以看到代碼中并未用到math.js中的square方法,webpack輸出文件中表示它未被使用。如果想去掉未被使用的代碼,則需要用到UglifyJSPlugin插件,它是用來(lái)壓縮js文件的,自動(dòng)啟用了去除冗余代碼的功能。我們可以在production模式下打包,會(huì)發(fā)現(xiàn)square的代碼已經(jīng)被去除。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/96606.html

相關(guān)文章

  • webpack4配置詳解之逐行分析

    摘要:今天就嘗試著一起來(lái)聊聊吧,旨在幫大家加深理解新手更容易上路,都能從到搭建配置自定屬于自己的腳手架,或?qū)σ逊庋b好的腳手架有進(jìn)一步的鞏固,接下來(lái)蘇南會(huì)詳細(xì)講解中的每一個(gè)配置字段的作用部分為新增。 showImg(https://segmentfault.com/img/bVbjmMV?w=1008&h=298); 前言   經(jīng)常會(huì)有群友問(wèn)起webpack、react、redux、甚至cre...

    dkzwm 評(píng)論0 收藏0
  • webpack4-Tree-Shaking優(yōu)化

    摘要:概念由來(lái)已久,今天再來(lái)談一談,是因?yàn)橹杏辛诵碌膬?yōu)化。簡(jiǎn)單的介紹下什么是。它已經(jīng)為我們消除了副作用。而且我并沒(méi)有引入。即便根據(jù)文件大小,可能還有朋友持懷疑態(tài)度。因?yàn)樽罱沤佑|。所以沒(méi)有在低版本的時(shí)候打包過(guò)。 Tree-Shaking概念由來(lái)已久,今天再來(lái)談一談,是因?yàn)閣ebpack4中有了新的優(yōu)化。簡(jiǎn)單的介紹下什么是Tree-Shaking。 代碼不會(huì)被執(zhí)行 if(false) { ...

    bawn 評(píng)論0 收藏0
  • webpack4系列教程(十):總結(jié)

    摘要:傳送門(mén)系列教程一初識(shí)系列教程二創(chuàng)建項(xiàng)目,打包第一個(gè)文件系列教程三自動(dòng)生成項(xiàng)目中的文件系列教程四處理項(xiàng)目中的資源文件一系列教程五處理項(xiàng)目中的資源文件二系列教程六使用分割代碼系列教程七使用系列教程八使用審查代碼系列教程九開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境 在前端開(kāi)發(fā)日益復(fù)雜的今天,我們需要一個(gè)工具來(lái)幫助我們管理項(xiàng)目資源,打包、編譯、預(yù)處理、后處理等等。webpack的出現(xiàn)無(wú)疑是前端開(kāi)發(fā)者的福音,我的博文只...

    hqman 評(píng)論0 收藏0
  • webpack4新特性介紹

    摘要:當(dāng)下最流行的模塊打包器于年月日正式發(fā)布版本,代號(hào)。從官方的發(fā)布日志來(lái)看本次大版本更新帶來(lái)了很多新特性更新和改善,這將會(huì)讓的配置更加簡(jiǎn)單。本文,筆者將會(huì)全面介紹的新特性及實(shí)踐。只支持模塊,目前處于試驗(yàn)階段。 導(dǎo)語(yǔ): webpack是一個(gè)JS應(yīng)用打包器, 它將應(yīng)用中的各個(gè)模塊打成一個(gè)或者多個(gè)bundle文件。借助loaders和plugins,它可以改變、壓縮和優(yōu)化各種各樣的文件。它的輸入...

    NotFound 評(píng)論0 收藏0
  • webpack4.0初體驗(yàn)、各版本及parcel性能對(duì)比

    摘要:前段時(shí)間又發(fā)布了新版本我接觸的時(shí)候已經(jīng)版本了支持的版本必須打包速度大小比較以及粗淺的試了一下下圖所示,黃色為版本綠色為我寫(xiě)的配置,跟基本相似,具體不同下面會(huì)介紹藍(lán)色是自帶的模式紅色為具體大小速度大家可以比較一下,還是很給力的關(guān)于配置方面,應(yīng) 前段時(shí)間webpack又發(fā)布了新版本webpack4我接觸的時(shí)候已經(jīng)4.1版本了node支持的版本必須node: >=6.11.5 webpack...

    MarvinZhang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<