亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

一看就懂之webpack基礎(chǔ)配置

woshicixide / 1849人閱讀

摘要:一看就懂之基礎(chǔ)配置一簡介本質(zhì)上,是一個現(xiàn)代應(yīng)用程序的靜態(tài)模塊打包器。屬性表示的是的上下文目錄,配置入口文件的時候,如果入口文件使用的是相對路徑,那么就是相對于所在的目錄。通常用于指定以何種方式導(dǎo)出庫,通常用于指定接收庫的名稱。

一看就懂之webpack基礎(chǔ)配置 一、webpack 簡介
本質(zhì)上,webpack 是一個現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時,它會遞歸地構(gòu)建一個依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個模塊,然后將所有這些模塊打包成一個或多個 bundle。
簡單說,webpack可以看做是一個模塊打包機,主要作用就是: 分析你的項目結(jié)構(gòu),找到JavaScript模塊以及一些瀏覽器不能直接運行的拓展語言(sass、less、typescript等),然后將它們打包為合適的格式以供瀏覽器使用。

webpack主要實現(xiàn)的功能:

代碼轉(zhuǎn)換(如: ES6轉(zhuǎn)換ES5、sass和less轉(zhuǎn)換為css等)
文件優(yōu)化(如: 將模塊內(nèi)容進行壓縮)
代碼分割(如: 多頁面應(yīng)用公共模塊的抽離、路由懶加載)
模塊合并(如: 按照不同的功能將多個模塊合并為一個模塊)
自動刷新(如: 啟動本地服務(wù),代碼更新后進行自動刷新)
代碼校驗(如: 添加eslint進行代碼規(guī)范檢查)
自動發(fā)布(如: 應(yīng)用打包完成后,自動發(fā)布)
二、webpack 安裝

在webpack 3中,webpack本身和它的CLI以前都是在同一個包中的,但在第4版之后,已經(jīng)將兩者分開來更好地管理它們,所以安裝webpack4之后的版本,要同時安裝webpack和webpack-cli

注意,安裝webpack的時候,必須進行本地安裝才能生效,否則會報錯,如:
但是全局安裝了也有一個好處,那就是可以在項目根目錄下直接執(zhí)行webpack即可完成項目的打包,如果沒有進行全局安裝,那么可以通過npx直接執(zhí)行項目本地安裝的模塊,即 npx webpack也可以完成項目的打包。
三、webpack 基礎(chǔ)配置

webpack是支持零配置的,即不需要配置文件即可完成打包,其默認(rèn)入口文件為項目根目錄下的src目錄下的index.js文件,其默認(rèn)出口為項目根目錄下的dist目錄的main.js

如果沒有給webpack添加配置文件,那么webpack的打包能力就會非常弱,webpack執(zhí)行的時候默認(rèn)會加載項目根目錄下的webpack.config.js文件,注意,該配置文件是一個js文件,而不是json文件,并且其是通過node去執(zhí)行的,所以其完全支持node語法,即node中能用的,在配置文件中都可以用
webpack配置文件必須要對外暴露一個對象,即通過module.exports進行對外暴露,其中的所有配置都必須寫在這個對外暴露的對象中。

context
context屬性表示的是webpack的上下文目錄,配置入口文件的時候,如果入口文件使用的是相對路徑,那么就是相對于context所在的目錄。

context默認(rèn)值為執(zhí)行webpack命令時所在的當(dāng)前工作目錄,通常是在項目根目錄下執(zhí)行webpack命令,所以可以認(rèn)為其值默認(rèn)為項目根目錄,所以如果入口文件路徑寫成相對路徑,最好將context配置成context: path.resolve(__dirname),以防止在非項目根目錄下執(zhí)行webpack命令時找不到入口文件路徑而報錯。

entry

entry用于配置模塊的入口文件,可以配置多個,webpack將從入口文件開始搜索以及遞歸解析所有入口文件依賴的模塊,其是必填的,如果配置文件中沒有entry則會報錯。entry的屬性值可以是表示路徑的單個字符串,也可以是數(shù)組,數(shù)組中的元素為入口文件的路徑,還可以是對象,對象的屬性名為入口文件的chunk名,即打包后輸出文件的名字,屬性值為入口文件的路徑。注意,入口文件的路徑可以是絕對路徑也可以是相對路徑,相對路徑默認(rèn)是以配置文件中的context屬性值表示的路徑
module.exports = {
    entry: "./foo.js" // 屬性值為一個表示路徑的字符串
}
其輸出結(jié)果文件取決于配置文件的output配置,如果output.filename沒有配置,則默認(rèn)輸出為main.js,如果output.filename值為指定的名稱,則輸出結(jié)果為output.filename的屬性值
module.exports = {
    entry: [ "./foo.js", "./bar.js"] // 屬性值為一個數(shù)組
}
其輸出結(jié)果文件也是取決于配置文件的output配置,只不過,其會將foo.js和bar.js一起打包輸出為一個文件,如果output.filename沒有配置,則默認(rèn)輸出為main.js,如果output.filename值為指定的名稱,則輸出結(jié)果為output.filename的屬性值
module.exports = {
    entry: { // 屬性值為一個對象
        a: "./src/bar.js",
        b: "./src/foo.js",
        c: "./src/index.js"
    }
}
其輸出結(jié)果不再取決于output.filename的配置,因為entry已經(jīng)指定好了模塊輸出的chunk名,即會分別輸出a.js、b.js和c.js三個文件,并且此時output.filename屬性值不能配置為一個固定名稱的輸出文件,因為入口文件有多個,必然輸出文件也會有多個
chunk和module的區(qū)別,二者都是表示模塊,但是module可以看做是具有獨立功能的小模塊,即小塊,也就是打包之前,程序員編寫的一個一個的文件,每個文件稱為一個module;而chunk則可以看做是由多個小module打包成的大模塊,即大塊

output
output配置的是如何輸出最終想要的代碼,output是一個object。

path: 用于配置打包后輸出文件的本地存放目錄,必須是絕對路徑,當(dāng)然也可以不配置,因為如果沒有配置path,那么會自動在執(zhí)行webpack命令時所在的目錄下自動創(chuàng)建dist目錄并將打包結(jié)果輸出到dist目錄下,與context的配置路徑無關(guān)

module.exports = {
    output: {
        path: path.resolve(__dirname, "./dist") // 必須是絕對路徑
    }
}

filename: 用于配置輸出文件的名稱,如果只有一個輸出文件,那么可以配置成靜態(tài)不變的文件名,如:

module.exports = {
    output: {
        filename: "bundle.js"
    }
}

但是,如果有多個chunk要輸出時,即入口文件配置了多個時,那么filename就不能配置成靜態(tài)不變的了,就必須借助模板和變量了,常見的兩個變量,如:
[name]: 可以自動獲取到入口文件配置的chunk名稱;
[hash]: 可以自動生成hash值,hash值的長度是可以指定的,默認(rèn)為20位;

module.exports = {
    output: {
        filename: "[name][hash:8].js" // 以入口文件設(shè)置的chunk作為輸出名,并且指定hash值為8位
    }
}

library和libraryTarget: 用于指定將模塊的輸出結(jié)果掛載到哪個地方或者以什么樣的方式導(dǎo)出庫(模塊輸出結(jié)果)。二者通常要搭配一起使用。
libraryTarget通常用于指定以何種方式導(dǎo)出庫,library通常用于指定接收庫的名稱。
我們將入口的一個或多個js文件打包輸出后的結(jié)果也是一個js文件,在沒有配置library和libraryTarget的時候,這個輸出的js文件中包含了一個匿名自執(zhí)行函數(shù), 即輸出文件的執(zhí)行結(jié)果沒有被任何東西接收,我們引入輸出文件執(zhí)行后不會得到任何結(jié)果。 如:

(function(){
    console.log("foo");
    return "foo"; // 雖然有返回值,但是匿名自執(zhí)行函數(shù)執(zhí)行完畢后拿不到任何結(jié)果
})();
// 我們以var 變量 的方式來接收函數(shù)的返回值
var foo = (function(){ // 匿名自執(zhí)行函數(shù)執(zhí)行完畢后就會將函數(shù)返回值保存到foo變量上
    console.log("foo");
    return "foo";
})();
console.log(`foo is ${foo}`);
打包后的輸出文件的輸出結(jié)果(導(dǎo)出結(jié)果),就是入口文件的輸出結(jié)果(導(dǎo)出結(jié)果),即入口文件通過export、exports、module.exports等輸出(導(dǎo)出)的結(jié)果

var: 將libraryTarget設(shè)置為var, 同時指定一個自定義的變量名來接收模塊的輸出,這個自定義的變量名就是library的屬性值

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "var",
        library: "test"
    }
}

模塊的輸出結(jié)果將會賦值給test變量,其輸出文件bundle.js內(nèi)容大致如下:

var test = (function(modules){
    return result; // 返回值result將會被賦值給test變量 
})();

commonjs: 將libraryTarget設(shè)置為commonjs, 即通過commonjs規(guī)范導(dǎo)出,同時指定一個自定義的變量名來接收模塊的輸出,這個自定義的變量名就是library的屬性值, 只不過這個自定義的變量名是exports的屬性名,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "commonjs",
        library: "test"
    }
}

模塊的輸出結(jié)果將會賦值給exports["test"]上,其輸出文件bundle.js內(nèi)容大致如下:

exports["test"] = (function(modules){
    return result; // 返回值result將會被賦值給exports["test"]
})();

commonjs2: 將libraryTarget設(shè)置為commonjs2,即通過commonjs2規(guī)范導(dǎo)出,此時library的配置將無意義,因為commonjs2的輸出是固定的module.exports,所以不需要指定library了,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "commonjs2"
    }
}

模塊的輸出結(jié)果將會被賦值到module.exports上,其輸出文件bundle.js內(nèi)容大致如下:

module.exports = (function(modules){
    return result; // 返回值result將會被賦值給module.exports
})();
commonjs和commonjs2的區(qū)別在于,commonjs只能使用exports進行導(dǎo)出,而commonjs2在commonjs的基礎(chǔ)上增加了module.exports進行導(dǎo)出;

this: 將libraryTarget設(shè)置為this, 那么此時library配置的變量名將作為this的屬性名來接收模塊的導(dǎo)出結(jié)果,如:

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        libraryTarget: "this",
        library: "test"
    }
}

模塊的輸出結(jié)果將會被賦值到this["test"] 上,其輸出文件bundle.js內(nèi)容大致如下:

this["test"] = (function(modules){
    return result; // 返回值result將會被賦值給this["test"]
})();

同理libraryTarget的屬性值還可以是window、global,這里就不一一列舉了。

publicPath
publicPath用于配置打包資源發(fā)布到線上時服務(wù)器的url地址,打包完成后,html文件中如果引入了js、image、css等資源,那么都會在前面加上publicPath所表示的路徑

module.exports = {
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "./dist/"),
        publicPath: "http://www.lihb.com/"
    }
}

// index.html




    
四、webpack 打包輸出后的內(nèi)容分析

webpack打包輸出后的結(jié)果默認(rèn)是一個匿名自執(zhí)行函數(shù),匿名自執(zhí)行函數(shù)傳遞的參數(shù)為一個對象,對象的屬性名為入口文件的路徑名,屬性值為一個函數(shù),函數(shù)體內(nèi)部通過會執(zhí)行eval(),eval()方法的參數(shù)為入口文件的內(nèi)容字符串,而這個匿名自執(zhí)行函數(shù),內(nèi)部有一個自定義的__webpack_require__方法,該方法需要傳入入口文件的路徑名作為參數(shù),匿名自執(zhí)行函數(shù)執(zhí)行完成后會返回__webpack_require__的結(jié)果,而__webpack_require__()方法內(nèi)部執(zhí)行的時候,會首先創(chuàng)建一個module對象,module對象里面有exports屬性,屬性值為一個空的對象,用于接收入口文件的模塊輸出,如:

(function(modules) {
    function __webpack_require__(moduleId) { // 傳入入口文件的路徑
        var module = installedModules[moduleId] = { // 創(chuàng)建一個module對象
             i: moduleId,
             l: false,
             exports: {} // exports對象用于保存入口文件的導(dǎo)出結(jié)果
         };
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); // 執(zhí)行入口文件
        return module.exports; // 返回模塊輸出結(jié)果
    }
    return __webpack_require__(__webpack_require__.s = "./src/bar.js"); // 返回入口文件
})({
     "./src/bar.js": (function(module, exports) {
         eval("module.exports = "bar";");
     })
  });
所以不管入口文件是以ES6模塊的方式輸出還是以commonjs模塊的方式輸出,最終入口文件的模塊輸出結(jié)果都會被綁定到__webpack_require__方法中定義的module對象的exports屬性上,只不過,如果是以commonjs的方式輸出,那么入口文件的輸出結(jié)果將會直接替換掉__webpack_require__方法中定義的module對象的exports屬性;如果是以ES6模塊的方式輸出,則是在__webpack_require__方法中定義的module對象的exports屬性值中添加一個default屬性或者具體變量名來保存入口文件的輸出。
五、webpack 本地服務(wù)器配置

為了更方便調(diào)試,我們需要用到webpack的本地http服務(wù)器功能,要想使用webpack提供的Web服務(wù)器功能,我們需要安裝webpack-dev-server模塊,webpack-dev-server會啟動一個web服務(wù)器用于實現(xiàn)網(wǎng)頁請求,也可以監(jiān)聽文件的變化自動刷新網(wǎng)頁。

webpack-dev-server模塊安裝完成后,我們可以在項目根目錄下運行npx webpack-dev-server,其和webpack命令一樣,如果沒有配置文件,則使用內(nèi)置默認(rèn)配置進行打包輸出,如果有則使用配置文件中的配置,只不過其不會將打包結(jié)果輸出到指定的目錄中,因為webpack-dev-server會忽略配置文件中的output.path配置,其會將打包輸出結(jié)果保存到內(nèi)存中。webpack-dev-server啟動后會默認(rèn)將啟動devServer時所在的目錄作為根目錄,即執(zhí)行npx webpack-dev-server命令時所在的目錄。

webpack提供了一個devServer屬性用于配置啟動的服務(wù)器的一些參數(shù),當(dāng)然webpack本身是無法識別devServer屬性配置的,只有通過webpack-dev-server去啟動webpack時,devServer的配置才會生效。

module.exports = {
    devServer: {
        port: 3000, // 讓devServer監(jiān)聽3000端口
        contentBase: "./dist", // 將當(dāng)前項目的dist目錄作為devServer的根目錄
        progress: true, // 顯示打包進度條
        compress: true // 是否啟用Gzip壓縮,默認(rèn)為false
    }
}
webpackDevServer啟動后,默認(rèn)會自動監(jiān)聽打包源文件的變化,如果修改了打包源文件,那么會自動重新打包到內(nèi)存,并且會自動刷新瀏覽器,但是自動刷新瀏覽器功能必須將target設(shè)置成web,否則自動刷新功能將會失效,比如target為node就無法起作用。
六、webpack 插件配置

在不使用插件的時候,webpack默認(rèn)只能打包輸出js文件,如果我們想要輸出其他格式的文件到輸出目錄中,那么我們必須使用插件。webpack提供了一個plugins屬性用于配置使用到的插件,其屬性值為一個數(shù)組,數(shù)組中的元素為插件對象,通常插件都是一個類,我們需要通過插件類來創(chuàng)建一個插件對象。
html-webpack-plugin
該插件可以指定一個html文件,webpack會將該html文件打包輸出到輸出目錄中,同時會將打包輸出后的文件自動插入到該html文件中,即讓該html文件自動引入打包后的js文件。

module.exports = {
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html", // 要打包輸出哪個文件,可以使用相對路徑
            filename: "index.html", // 打包輸出后該html文件的名稱
            minify: {
                removeAttributeQuotes: true, // 去除html文件中的引號
                collapseWhitespace: true // 合并空格,即將html進行單行顯示
            },
            hash: true // 向html文件中引入打包后的js時候帶上hash值
        })
    ]
}
html插件中配置了hash為true, 是在引入打包后的js的時候帶上hash值,如:
七、webpack 模塊配置

webpack默認(rèn)將所有格式的文件都當(dāng)做模塊進行處理,但是wepback默認(rèn)只能處理js模塊。如果在js中通過require引入了其他格式的模塊(文件),那么webpack就必須通過安裝合適的模塊加載器,才能正確解析對應(yīng)的模塊內(nèi)容,webpack提供了一個module屬性,用于進行模塊解析器的配置,其屬性值為一個對象,對象中有一個rules屬性,其屬性值為一個數(shù)組,數(shù)組中的元素為一個對象,該對象主要完成兩件事,匹配對應(yīng)格式的文件,并且使用對應(yīng)模塊加載器進行加載,匹配使用的是test屬性,屬性值為一個正則表達(dá)式,【使用】使用的是use屬性,屬性值可以是字符串也可以是數(shù)組,如果只有一個模塊加載器的時候,可以使用字符串的形式,如果有多個模塊加載器的時候,那么就需要使用數(shù)組的形式,當(dāng)然,如果模塊加載器需要傳遞參數(shù)配置,那么可以將模塊加載器寫成對象的形式,通過loader屬性指定模塊加載器名稱,通過options屬性傳遞參數(shù)配置。

① 處理css樣式,需要使用到css-loader和style-loader。
首先需要安裝css-loader和style-loader。
css-loader必須同時和style-loader一起使用才能正確加載css文件,一個負(fù)責(zé)加載,一個負(fù)責(zé)插入。css-loader負(fù)責(zé)加載css, 即在js文件中能夠通過require的方式引入css,即加載和解析css,同時支持在css文件中使用@ import的方式引入其他css文件,style-loader負(fù)責(zé)將加載并解析好的css文件插入到html文件中去,從名字可以看出其是在html文件中生成style標(biāo)簽來引入css文件,loader的執(zhí)行順序是從右向左,所以必須先加載然后再插入

比如,打包入口文件index.js中通過require的方式引入了一個index.js文件,即require("./index.css"),那么webpack需要進行如下配置:

module.exports = {
    module: {
        rules: [
            {
                test: /.css$/, // 匹配以.css結(jié)尾的文件
                use: [ // 并交給css-loader和style-loader進行處理
                    {
                        loader: "style-loader", // 以對象的形式配置loader
                        options: { // 通過options給loader傳遞參數(shù)
                            insertAt: "top" // 默認(rèn)為bottom, 將加載的css文件插入到head標(biāo)簽的最上面,即優(yōu)先級最低,會被覆蓋
                        }
                    },
                    "css-loader" // 直接以字符串的形式配置loader
                ]
            }
        ]
    }
}
打包輸出后,會將index.css中的內(nèi)容放到
<pre id="w1bic"><fieldset id="w1bic"></fieldset></pre>
    <ruby id="w1bic"></ruby>
      1. <abbr id="w1bic"><thead id="w1bic"></thead></abbr>
        <