成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

9102年:手寫一個(gè)React腳手架 【優(yōu)化極致版】

whatsns / 1038人閱讀

摘要:馬上要出了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。每個(gè)依賴項(xiàng)隨即被處理,最后輸出到稱之為的文件中,我們將在下一章節(jié)詳細(xì)討論這個(gè)過程。的事件流機(jī)制保證了插件的有序性,使得整個(gè)系統(tǒng)擴(kuò)展性很好。

webpack馬上要出5了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。

本文書寫時(shí)間 2019年5月9日 , webpack版本 4.30.0最新版本

本人所有代碼均手寫,親自試驗(yàn)過可以運(yùn)行達(dá)到優(yōu)化效果。

歡迎關(guān)注我的專欄 《前端進(jìn)階》 以后都是高贊高質(zhì)量文章

要轉(zhuǎn)載必須聯(lián)系本人經(jīng)過同意才可轉(zhuǎn)載 謝謝!

杜絕5分鐘的技術(shù),我們先深入原理再寫配置,那會(huì)簡單很多。

我這套代碼,在開發(fā)環(huán)境中性能不是完美的,但是構(gòu)建速度打包生產(chǎn)環(huán)境代碼是極快的,請你一定要去看我的git倉庫,現(xiàn)在已經(jīng)加入了項(xiàng)目實(shí)踐,也在里面,可以的話給個(gè)star
實(shí)現(xiàn)需求:

識別JSX文件

tree shaking 搖樹優(yōu)化 刪除掉無用代碼

識別 async / await 和 箭頭函數(shù)

PWA功能,熱刷新,安裝后立即接管瀏覽器 離線后仍讓可以訪問網(wǎng)站 還可以在手機(jī)上添加網(wǎng)站到桌面使用

preload 預(yù)加載資源 prefetch按需請求資源

CSS模塊化,不怕命名沖突

小圖片的base64處理

文件后綴省掉jsx js json

實(shí)現(xiàn)React懶加載,按需加載 , 代碼分割 并且支持服務(wù)端渲染

支持less sass stylus等預(yù)處理

code spliting 優(yōu)化首屏加載時(shí)間 不讓一個(gè)文件體積過大

加入dns-prefetchpreload預(yù)請求必要的資源,加快首屏渲染。

加入prerender,極大加快首屏渲染速度。

提取公共代碼,打包成一個(gè)chunk

每個(gè)chunk有對應(yīng)的chunkhash,每個(gè)文件有對應(yīng)的contenthash,方便瀏覽器區(qū)別緩存

圖片壓縮

CSS壓縮

增加CSS前綴 兼容各種瀏覽器

對于各種不同文件打包輸出指定文件夾下

緩存babel的編譯結(jié)果,加快編譯速度

每個(gè)入口文件,對應(yīng)一個(gè)chunk,打包出來后對應(yīng)一個(gè)文件 也是code spliting

刪除HTML文件的注釋等無用內(nèi)容

每次編譯刪除舊的打包代碼

CSS文件多帶帶抽取出來

讓babel不僅緩存編譯結(jié)果,還在第一次編譯后開啟多線程編譯,極大加快構(gòu)建速度

等等....

webpack中文官網(wǎng)的標(biāo)語是 :讓一切都變得簡單

概念: 本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle webpack v4.0.0 開始,可以不用引入一個(gè)配置文件。然而,webpack 仍然還是高度可配置的。在開始前你需要先理解四個(gè)核心概念:

入口(entry)

輸出(output)

loader

插件(plugins)

本文旨在給出這些概念的高度概述,同時(shí)提供具體概念的詳盡相關(guān)用例。

讓我們一起來復(fù)習(xí)一下最基礎(chǔ)的Webpack知識,如果你是高手,那么請直接忽略這些往下看吧....

入口

入口起點(diǎn)`(entry point)指示 webpack 應(yīng)該使用哪個(gè)模塊,來作為構(gòu)建其內(nèi)部依賴圖的開始。進(jìn)入入口起點(diǎn)后,webpack 會(huì)找出有哪些模塊和庫是入口起點(diǎn)(直接和間接)依賴的。

每個(gè)依賴項(xiàng)隨即被處理,最后輸出到稱之為 bundles 的文件中,我們將在下一章節(jié)詳細(xì)討論這個(gè)過程。

可以通過在 webpack 配置中配置 entry 屬性,來指定一個(gè)入口起點(diǎn)(或多個(gè)入口起點(diǎn))。默認(rèn)值為 ./src。

接下來我們看一個(gè) entry 配置的最簡單例子:

webpack.config.js

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

入口可以是一個(gè)對象,也可以是一個(gè)純數(shù)組

entry: {
    app: ["./src/index.js", "./src/index.html"],
    vendor: ["react"] 
},
entry: ["./src/index.js", "./src/index.html"],

有人可能會(huì)說,入口怎么放HTML文件,因?yàn)殚_發(fā)模式下熱更新如果不設(shè)置入口為HTML,那么更改了HTML文件內(nèi)容,是不會(huì)刷新頁面的,需要手動(dòng)刷新,所以這里給了入口HTML文件,一個(gè)細(xì)節(jié)。

出口(output)

output 屬性告訴 webpack 在哪里輸出它所創(chuàng)建的 bundles,以及如何命名這些文件,默認(rèn)值為 ./dist?;旧希麄€(gè)應(yīng)用程序結(jié)構(gòu),都會(huì)被編譯到你指定的輸出路徑的文件夾中。你可以通過在配置中指定一個(gè) output 字段,來配置這些處理過程:

    webpack.config.js
    
    const path = require("path");
    
    module.exports = {
      entry: "./path/to/my/entry/file.js",
      output: {
        path: path.resolve(__dirname, "dist"),
        filename: "my-first-webpack.bundle.js"
      }
    };

在上面的示例中,我們通過 output.filenameoutput.path 屬性,來告訴 webpack bundle 的名稱,以及我們想要 bundle 生成(emit)到哪里??赡苣阆胍私庠诖a最上面導(dǎo)入的 path 模塊是什么,它是一個(gè) Node.js 核心模塊,用于操作文件路徑。

loader

loader 讓 webpack 能夠去處理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以將所有類型的文件轉(zhuǎn)換為 webpack 能夠處理的有效模塊,然后你就可以利用 webpack 的打包能力,對它們進(jìn)行處理。

本質(zhì)上,webpack loader 將所有類型的文件,轉(zhuǎn)換為應(yīng)用程序的依賴圖(和最終的 bundle)可以直接引用的模塊。

注意,loader 能夠 import 導(dǎo)入任何類型的模塊(例如 .css 文件),這是 webpack 特有的功能,其他打包程序或任務(wù)執(zhí)行器的可能并不支持。我們認(rèn)為這種語言擴(kuò)展是有很必要的,因?yàn)檫@可以使開發(fā)人員創(chuàng)建出更準(zhǔn)確的依賴關(guān)系圖。

在更高層面,在 webpack 的配置中 loader 有兩個(gè)目標(biāo):

test 屬性,用于標(biāo)識出應(yīng)該被對應(yīng)的 loader 進(jìn)行轉(zhuǎn)換的某個(gè)或某些文件。

use 屬性,表示進(jìn)行轉(zhuǎn)換時(shí),應(yīng)該使用哪個(gè) loader。

    webpack.config.js
    
    const path = require("path");
    
    const config = {
      output: {
        filename: "my-first-webpack.bundle.js"
      },
      module: {
        rules: [
          { test: /.txt$/, use: "raw-loader" }
        ]
      }
    };
    
    module.exports = config;

以上配置中,對一個(gè)多帶帶的 module 對象定義了 rules 屬性,里面包含兩個(gè)必須屬性:test 和 use。這告訴 webpack 編譯器(compiler) 如下信息:

“嘿,webpack 編譯器,當(dāng)你碰到「在 require()/import 語句中被解析為 ".txt" 的路徑」時(shí),在你對它打包之前,先使用 raw-loader轉(zhuǎn)換一下。”

重要的是要記得,在 webpack 配置中定義 loader 時(shí),要定義在 module.rules 中,而不是 rules。然而,在定義錯(cuò)誤時(shí) webpack 會(huì)給出嚴(yán)重的警告。為了使你受益于此,如果沒有按照正確方式去做,webpack 會(huì)“給出嚴(yán)重的警告”

loader 還有更多我們尚未提到的具體配置屬性。

這里引用這位作者的優(yōu)質(zhì)文章內(nèi)容,手寫一個(gè)loaderplugin 手寫一個(gè)loader和plugin

高潮來了 ,webpack的編譯原理 ,為什么要先學(xué)學(xué)習(xí)原理? 因?yàn)槟闫鸫a得知道你寫的是干什么的!

webpack打包原理

識別入口文件

通過逐層識別模塊依賴。(Commonjs、amd或者es6的import,webpack都會(huì)對其進(jìn)行分析。來獲取代碼的依賴)

webpack做的就是分析代碼。轉(zhuǎn)換代碼,編譯代碼,輸出代碼

最終形成打包后的代碼

這些都是webpack的一些基礎(chǔ)知識,對于理解webpack的工作機(jī)制很有幫助。

什么是loader

loader是文件加載器,能夠加載資源文件,并對這些文件進(jìn)行一些處理,諸如編譯、壓縮等,最終一起打包到指定的文件中

處理一個(gè)文件可以使用多個(gè)loaderloader的執(zhí)行順序是和本身的順序是相反的,即最后一個(gè)loader最先執(zhí)行,第一個(gè)loader最后執(zhí)行。

第一個(gè)執(zhí)行的loader接收源文件內(nèi)容作為參數(shù),其他loader接收前一個(gè)執(zhí)行的loader的返回值作為參數(shù)。最后執(zhí)行的loader會(huì)返回此模塊的JavaScript源碼

在使用多個(gè)loader處理文件時(shí),如果要修改outputPath輸出目錄,那么請?jiān)谧钌厦娴?b>loader中options設(shè)置

什么是plugin?

Webpack 運(yùn)行的生命周期中會(huì)廣播出許多事件,Plugin 可以監(jiān)聽這些事件,在合適的時(shí)機(jī)通過 Webpack 提供的 API 改變輸出結(jié)果。

plugin和loader的區(qū)別是什么?

對于loader,它就是一個(gè)轉(zhuǎn)換器,將A文件進(jìn)行編譯形成B文件,這里操作的是文件,比如將A.scss或A.less轉(zhuǎn)變?yōu)锽.css,單純的文件轉(zhuǎn)換過程

plugin是一個(gè)擴(kuò)展器,它豐富了wepack本身,針對是loader結(jié)束后,webpack打包的整個(gè)過程,它并不直接操作文件,而是基于事件機(jī)制工作,會(huì)監(jiān)聽webpack打包過程中的某些節(jié)點(diǎn),執(zhí)行廣泛的任務(wù)。

webpack的運(yùn)行

webpack 啟動(dòng)后,在讀取配置的過程中會(huì)先執(zhí)行 new MyPlugin(options) 初始化一個(gè) MyPlugin 獲得其實(shí)例。在初始化compiler 對象后,再調(diào)用 myPlugin.apply(compiler) 給插件實(shí)例傳入 compiler 對象。插件實(shí)例在獲取到 compiler 對象后,就可以通過 compiler.plugin(事件名稱, 回調(diào)函數(shù)) 監(jiān)聽到 Webpack 廣播出來的事件。并且可以通過 compiler 對象去操作 webpack

看到這里可能會(huì)問compiler是啥,compilation又是啥?

Compiler 對象包含了 Webpack 環(huán)境所有的的配置信息,包含 options,loaders,plugins 這些信息,這個(gè)對象在 Webpack 啟動(dòng)時(shí)候被實(shí)例化,它是全局唯一的,可以簡單地把它理解為 Webpack 實(shí)例;

Compilation 對象包含了當(dāng)前的模塊資源、編譯生成資源、變化的文件等。當(dāng) Webpack 以開發(fā)模式運(yùn)行時(shí),每當(dāng)檢測到一個(gè)文件變化,一次新的 Compilation 將被創(chuàng)建。Compilation 對象也提供了很多事件回調(diào)供插件做擴(kuò)展。通過 Compilation 也能讀取到 Compiler 對象。

CompilerCompilation 的區(qū)別在于:

Compiler 代表了整個(gè) Webpack 從啟動(dòng)到關(guān)閉的生命周期,而 Compilation 只是代表了一次新的編譯。

事件流

webpack 通過?Tapable?來組織這條復(fù)雜的生產(chǎn)線。

webpack 的事件流機(jī)制保證了插件的有序性,使得整個(gè)系統(tǒng)擴(kuò)展性很好。

webpack的事件流機(jī)制應(yīng)用了觀察者模式,和 Node.js 中的 EventEmitter 非常相似。

下面正式開始開發(fā)環(huán)境的配置:

入口設(shè)置 :

設(shè)置APP,幾個(gè)入口文件,即會(huì)最終分割成幾個(gè)chunk

在入口中配置 vendor,可以code spliting ,將這些公共的復(fù)用代碼最終抽取成一個(gè)chunk,多帶帶打包出來

要想在開發(fā)模式中HMTL文件也熱更新,需要加入·index.html為入口文件

    entry: {
            app: ["./src/index.js", "./src/index.html"],
            vendor: ["react"]  //這里還可以加入redux react-redux better-scroll等公共代碼 
        },

output出口

webpack基于Node.js環(huán)境運(yùn)行,可以使用Node.jsAPI,path模塊的resolve方法

對輸出的JS文件,加入contenthash標(biāo)示,讓瀏覽器緩存文件,區(qū)別版本。

     output: {
            filename: "[name].[contenthash:8].js",
            path: resolve(__dirname, "../dist")
        },

mode: "development" 模式選擇,這里直接設(shè)置成開發(fā)模式,先從開發(fā)模式開始。

resolve解析配置,為了為了給所有文件后綴省掉 js jsx json,加入配置

resolve: {
    extensions: [".js", ".json", ".jsx"]
}

加入插件 熱更新pluginhtml-webpack-plugin

   
   const HtmlWebpackPlugin = require("html-webpack-plugin")
   const webpack = require("webpack")
   new HtmlWebpackPlugin({
           template: "./src/index.html"
       }),
   new webpack.HotModuleReplacementPlugin(),

加入代碼分割,開發(fā)模式也需要代碼分割,性能優(yōu)化

optimization: {
        runtimeChunk: true,
        splitChunks: {
            chunks: "all"
        }
    }

加入 babel-loader 還有 解析JSX ES6語法的 babel preset

@babel/preset-react解析 jsx語法

@babel/preset-env解析es6語法

@babel/plugin-syntax-dynamic-import解析react-loadableimport按需加載,附帶code spliting功能

["import", { libraryName: "antd-mobile", style: true }], Antd-mobile的按需加載

{
                            loader: "babel-loader",
                            options: {   //jsx語法
                                presets: ["@babel/preset-react",
                                    //tree shaking 按需加載babel-polifill
                                    ["@babel/preset-env", { "modules": false, "useBuiltIns": "false", "corejs": 2 }]],
                                plugins: [
                                    //支持import 懶加載 
                                    "@babel/plugin-syntax-dynamic-import",
                                    //andt-mobile按需加載  true是less,如果不用less style的值可以寫"css" 
                                    ["import", { libraryName: "antd-mobile", style: true }],
                                    //識別class組件
                                    ["@babel/plugin-proposal-class-properties", { "loose": true }],
                                ],
                                cacheDirectory: true
                            },
                        }

加入thread-loader,在babel首次編譯后開啟多線程

    const os = require("os")
    {
            loader: "thread-loader",
            options: {
                workers: os.cpus().length   
                     }
    }



React的按需加載,附帶代碼分割功能 ,每個(gè)按需加載的組件打包后都會(huì)被多帶帶分割成一個(gè)文件

        import React from "react"
        import loadable from "react-loadable"
        import Loading from "../loading" 
        const LoadableComponent = loadable({
            loader: () => import("../Test/index.jsx"),
            loading: Loading,
        });
        class Assets extends React.Component {
            render() {
                return (
                    
這即將按需加載
) } } export default Assets

加入html-loader識別html文件

    {
    test: /.(html)$/,
    loader: "html-loader"
    }

加入eslint-loader

        {
        enforce:"pre",
        test:/.js$/,
        exclude:/node_modules/,
        include:resolve(__dirname,"/src/js"),
        loader:"eslint-loader"
        }

開發(fā)模式結(jié)束 代碼在下面的git倉庫里

必須了解的webpack熱更新原理 :

webpack的熱更新又稱熱替換(Hot Module Replacement),縮寫為HMR。 這個(gè)機(jī)制可以做到不用刷新瀏覽器而將新變更的模塊替換掉舊的模塊。

首先要知道server端和client端都做了處理工作

第一步,在 webpack 的 watch 模式下,文件系統(tǒng)中某一個(gè)文件發(fā)生修改,webpack 監(jiān)聽到文件變化,根據(jù)配置文件對模塊重新編譯打包,并將打包后的代碼通過簡單的 JavaScript 對象保存在內(nèi)存中。

第二步是 webpack-dev-server webpack 之間的接口交互,而在這一步,主要是 dev-server 的中間件 webpack-dev-middleware 和 webpack 之間的交互,webpack-dev-middleware 調(diào)用 webpack 暴露的 API對代碼變化進(jìn)行監(jiān)控,并且告訴 webpack,將代碼打包到內(nèi)存中。

第三步是 webpack-dev-server 對文件變化的一個(gè)監(jiān)控,這一步不同于第一步,并不是監(jiān)控代碼變化重新打包。當(dāng)我們在配置文件中配置了devServer.watchContentBase 為 true 的時(shí)候,Server 會(huì)監(jiān)聽這些配置文件夾中靜態(tài)文件的變化,變化后會(huì)通知瀏覽器端對應(yīng)用進(jìn)行 live reload。注意,這兒是瀏覽器刷新,和 HMR 是兩個(gè)概念。

第四步也是 webpack-dev-server 代碼的工作,該步驟主要是通過 sockjs(webpack-dev-server 的依賴)在瀏覽器端和服務(wù)端之間建立一個(gè) websocket 長連接,將 webpack 編譯打包的各個(gè)階段的狀態(tài)信息告知瀏覽器端,同時(shí)也包括第三步中 Server 監(jiān)聽靜態(tài)文件變化的信息。瀏覽器端根據(jù)這些 socket 消息進(jìn)行不同的操作。當(dāng)然服務(wù)端傳遞的最主要信息還是新模塊的 hash 值,后面的步驟根據(jù)這一 hash 值來進(jìn)行模塊熱替換。

webpack-dev-server/client 端并不能夠請求更新的代碼,也不會(huì)執(zhí)行熱更模塊操作,而把這些工作又交回給了 webpack,webpack/hot/dev-server 的工作就是根據(jù) webpack-dev-server/client 傳給它的信息以及 dev-server 的配置決定是刷新瀏覽器呢還是進(jìn)行模塊熱更新。當(dāng)然如果僅僅是刷新瀏覽器,也就沒有后面那些步驟了。

HotModuleReplacement.runtime 是客戶端 HMR 的中樞,它接收到上一步傳遞給他的新模塊的 hash 值,它通過 JsonpMainTemplate.runtime 向 server 端發(fā)送 Ajax 請求,服務(wù)端返回一個(gè) json,該 json 包含了所有要更新的模塊的 hash 值,獲取到更新列表后,該模塊再次通過 jsonp 請求,獲取到最新的模塊代碼。這就是上圖中 7、8、9 步驟。

而第 10 步是決定 HMR 成功與否的關(guān)鍵步驟,在該步驟中,HotModulePlugin 將會(huì)對新舊模塊進(jìn)行對比,決定是否更新模塊,在決定更新模塊后,檢查模塊之間的依賴關(guān)系,更新模塊的同時(shí)更新模塊間的依賴引用。

最后一步,當(dāng) HMR 失敗后,回退到 live reload 操作,也就是進(jìn)行瀏覽器刷新來獲取最新打包代碼。

參考文章 webpack面試題-騰訊云

正式開始生產(chǎn)環(huán)節(jié):

加入 WorkboxPlugin , PWA的插件

pwa這個(gè)技術(shù)其實(shí)要想真正用好,還是需要下點(diǎn)功夫,它有它的生命周期,以及它在瀏覽器中熱更新帶來的副作用等,需要認(rèn)真研究。可以參考百度的lavas框架發(fā)展歷史~

const WorkboxPlugin = require("workbox-webpack-plugin")


    new WorkboxPlugin.GenerateSW({ 
                clientsClaim: true, //讓瀏覽器立即servece worker被接管
                skipWaiting: true,  // 更新sw文件后,立即插隊(duì)到最前面 
                importWorkboxFrom: "local",
                include: [/.js$/, /.css$/, /.html$/,/.jpg/,/.jpeg/,/.svg/,/.webp/,/.png/],
            }),
        

加入每次打包輸出文件清空上次打包文件的插件

    const CleanWebpackPlugin = require("clean-webpack-plugin")
    
    new CleanWebpackPlugin()

加入code spliting代碼分割

    optimization: {
            runtimeChunk:true,  //設(shè)置為 true, 一個(gè)chunk打包后就是一個(gè)文件,一個(gè)chunk對應(yīng)`一些js css 圖片`等
            splitChunks: {
                chunks: "all"  // 默認(rèn) entry 的 chunk 不會(huì)被拆分, 配置成 all, 就可以了拆分了,一個(gè)入口`JS`,
                //打包后就生成一個(gè)多帶帶的文件
            }
        }

加入多帶帶抽取CSS文件的loader和插件

const MiniCssExtractPlugin = require("mini-css-extract-plugin")

    {
        test: /.(less)$/,
        use: [
            MiniCssExtractPlugin.loader,
            {
                loader: "css-loader", options: {
                    modules: true,
                    localIdentName: "[local]--[hash:base64:5]"
                }
            },
            {loader:"postcss-loader"},
            { loader: "less-loader" }
        ]
    }
    
     new MiniCssExtractPlugin({
            filename:"[name].[contenthash:8].css"
        }),

加入壓縮css的插件

    const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin")
    new OptimizeCssAssetsWebpackPlugin({
                cssProcessPluginOptions:{
                    preset:["default",{discardComments: {removeAll:true} }]
                }
            }),

殺掉html一些沒用的代碼

    new HtmlWebpackPlugin({
        template: "./src/index.html",
        minify: {
            removeComments: true,  
            collapseWhitespace: true,  
            removeRedundantAttributes: true,
            useShortDoctype: true, 
            removeEmptyAttributes: true,
            removeStyleLinkTypeAttributes: true,
            keepClosingSlash: true, 
            minifyJS: true,
            minifyCSS: true, 
            minifyURLs: true, 
         }
}),

加入圖片壓縮

{
                test: /.(jpg|jpeg|bmp|svg|png|webp|gif)$/,
                
                use:[
                    {loader: "url-loader",
                    options: {
                        limit: 8 * 1024,
                        name: "[name].[hash:8].[ext]",
                        outputPath:"/img"
                    }},
                    {
                        loader: "img-loader",
                        options: {
                          plugins: [
                            require("imagemin-gifsicle")({
                              interlaced: false
                            }),
                            require("imagemin-mozjpeg")({
                              progressive: true,
                              arithmetic: false
                            }),
                            require("imagemin-pngquant")({
                              floyd: 0.5,
                              speed: 2
                            }),
                            require("imagemin-svgo")({
                              plugins: [
                                { removeTitle: true },
                                { convertPathData: false }
                              ]
                            })
                          ]
                        }
                      }
                ]
                
                

            }

加入file-loader 把一些文件打包輸出到固定的目錄下

{
                exclude: /.(js|json|less|css|jsx)$/,
                loader: "file-loader",
                options: {
                    outputPath: "media/",
                    name: "[name].[contenthash:8].[ext]"
                }
            }
            
里面有一些注釋可能不詳細(xì),代碼都是自己一點(diǎn)點(diǎn)寫,試過的,肯定沒用任何問題

需要的依賴

{
    "name": "webpack",
    "version": "1.0.0",
    "main": "index.js",
    "license": "MIT",
    "dependencies": {
        "@babel/core": "^7.4.4",
        "@babel/preset-env": "^7.4.4",
        "@babel/preset-react": "^7.0.0",
        "autoprefixer": "^9.5.1",
        "babel-loader": "^8.0.5",
        "clean-webpack-plugin": "^2.0.2",
        "css-loader": "^2.1.1",
        "eslint": "^5.16.0",
        "eslint-loader": "^2.1.2",
        "file-loader": "^3.0.1",
        "html-loader": "^0.5.5",
        "html-webpack-plugin": "^3.2.0",
        "imagemin": "^6.1.0",
        "imagemin-gifsicle": "^6.0.1",
        "imagemin-mozjpeg": "^8.0.0",
        "imagemin-pngquant": "^7.0.0",
        "imagemin-svgo": "^7.0.0",
        "img-loader": "^3.0.1",
        "less": "^3.9.0",
        "less-loader": "^5.0.0",
        "mini-css-extract-plugin": "^0.6.0",
        "optimize-css-assets-webpack-plugin": "^5.0.1",
        "postcss-loader": "^3.0.0",
        "react": "^16.8.6",
        "react-dom": "^16.8.6",
        "react-loadable": "^5.5.0",
        "react-redux": "^7.0.3",
        "style-loader": "^0.23.1",
        "url-loader": "^1.1.2",
        "webpack": "^4.30.0",
        "webpack-cli": "^3.3.2",
        "webpack-dev-server": "^3.3.1",
        "workbox-webpack-plugin": "^4.3.1"
    },
    "scripts": {
        "start": "webpack-dev-server --config ./config/webpack.dev.js",
        "dev": "webpack-dev-server --config ./config/webpack.dev.js",
        "build": "webpack  --config  ./config/webpack.prod.js "
    },
    "devDependencies": {
        "@babel/plugin-syntax-dynamic-import": "^7.2.0"
    }
}

整個(gè)項(xiàng)目和webpack配置的源碼地址 已經(jīng)更新 : 源碼地址啊 看得見嗎親 路過的小伙伴麻煩點(diǎn)個(gè)贊給個(gè)star,寫得好辛苦?。。。?!

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/114596.html

相關(guān)文章

  • 前端之從零開始系列

    摘要:只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙只有動(dòng)手,你才能真正掌握一門技術(shù)持續(xù)更新中項(xiàng)目地址求求求源碼系列跟一起學(xué)如何寫函數(shù)庫中高級前端面試手寫代碼無敵秘籍如何用不到行代碼寫一款屬于自己的類庫原理講解實(shí)現(xiàn)一個(gè)對象遵循規(guī)范實(shí)戰(zhàn)手摸手,帶你用擼 Do it yourself!!! 只有動(dòng)手,你才能真的理解作者的構(gòu)思的巧妙 只有動(dòng)手,你才能真正掌握一門技術(shù) 持續(xù)更新中…… 項(xiàng)目地址 https...

    Youngdze 評論0 收藏0
  • 9102手寫一個(gè)React手架優(yōu)化極致

    摘要:馬上要出了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。每個(gè)依賴項(xiàng)隨即被處理,最后輸出到稱之為的文件中,我們將在下一章節(jié)詳細(xì)討論這個(gè)過程。的事件流機(jī)制保證了插件的有序性,使得整個(gè)系統(tǒng)擴(kuò)展性很好。 webpack馬上要出5了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。 本文書寫時(shí)間 2019年5月9日 , webpack版本 4.30.0最新版本 本人所有代碼均手寫,親自試驗(yàn)過可...

    Kylin_Mountain 評論0 收藏0
  • 9102手寫一個(gè)React手架優(yōu)化極致

    摘要:馬上要出了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。每個(gè)依賴項(xiàng)隨即被處理,最后輸出到稱之為的文件中,我們將在下一章節(jié)詳細(xì)討論這個(gè)過程。的事件流機(jī)制保證了插件的有序性,使得整個(gè)系統(tǒng)擴(kuò)展性很好。 webpack馬上要出5了,完全手寫一個(gè)優(yōu)化后的腳手架是不可或缺的技能。 本文書寫時(shí)間 2019年5月9日 , webpack版本 4.30.0最新版本 本人所有代碼均手寫,親自試驗(yàn)過可...

    bingo 評論0 收藏0
  • webpack4大結(jié)局:加入騰訊IM配置策略,實(shí)現(xiàn)前端工程化環(huán)境極致優(yōu)化

    摘要:或者的,都會(huì)對其進(jìn)行分析。舒適的開發(fā)體驗(yàn),有助于提高我們的開發(fā)效率,優(yōu)化開發(fā)體驗(yàn)也至關(guān)重要組件熱刷新熱刷新自從推出熱刷新后,前端開發(fā)者在開環(huán)境下體驗(yàn)大幅提高。實(shí)現(xiàn)熱調(diào)試后,調(diào)試流程大幅縮短,和普通非直出模式調(diào)試體驗(yàn)保持一致。 showImg(https://segmentfault.com/img/bVbtOR3?w=1177&h=635); webpack,打包所有的資源 不知道不...

    李增田 評論0 收藏0

發(fā)表評論

0條評論

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