webpack打包相關(guān)

webpack 是一個現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)饺汹。當(dāng) webpack 處理應(yīng)用程序時借尿,它會遞歸地構(gòu)建一個依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個模塊鸯两,然后將所有這些模塊打包成一個或多個 bundle。

1.webpack 介紹

模塊化思想:

  1. 按照代碼的業(yè)務(wù)邏輯進(jìn)行劃分,分成一塊一塊沮峡,模塊復(fù)用化,提高效率亿柑。
  2. 項(xiàng)目按照不同類型的文件邢疙,分別進(jìn)行不同的管理

組件化思想:
組件化思想是對于不同的頁面,使用不同的組件望薄,從頁面的角度考慮疟游,是否有公共組件,實(shí)現(xiàn)組件復(fù)用痕支,組件化颁虐。(vue、react)

webpack可以看做是模塊打包機(jī):它做的事情是卧须,分析你的項(xiàng)目結(jié)構(gòu)另绩,找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語言(Scss儒陨,TypeScript等)、文件等笋籽,并將其轉(zhuǎn)換和打包為合適的格式供瀏覽器使用蹦漠。

2. webpack和Grunt和Gulp比較

Webpack和另外兩個并沒有太多的可比性,Gulp/Grunt是一種能夠優(yōu)化前端的開發(fā)流程的工具车海,而webpack是一種模塊化的解決方案笛园,不過Webpack的優(yōu)點(diǎn)使得Webpack在很多場景下可以替代Gulp/Grunt類的工具。
Grunt和Gulp的工作方式是:在一個配置文件中侍芝,指明對某些文件進(jìn)行類似編譯研铆,組合,壓縮等任務(wù)的具體步驟竭贩,工具之后可以自動替你完成這些任務(wù)蚜印。
Webpack的工作方式是:把你的項(xiàng)目當(dāng)做一個整體,通過一個給定的主文件(如:index.js)留量,Webpack將從這個文件開始找到你的項(xiàng)目的所有依賴文件窄赋,使用loaders處理它們,最后打包為一個(或多個)瀏覽器可識別的JavaScript文件楼熄。

3.webpack核心概念

3.1 入口(entry)

入口起點(diǎn)(entry point)指示 webpack 應(yīng)該使用哪個模塊忆绰,來作為構(gòu)建其內(nèi)部依賴圖的開始。進(jìn)入入口起點(diǎn)后可岂,webpack 會找出有哪些模塊和庫是入口起點(diǎn)(直接和間接)依賴的错敢。
entry: {[entryChunkName: string]: string|Array<string>}

// 在多頁應(yīng)用中,(譯注:每當(dāng)頁面跳轉(zhuǎn)時)服務(wù)器將為你獲取一個新的 HTML 文檔缕粹。頁面重新加載新文檔稚茅,并且資源被重新下載
// 使用 CommonsChunkPlugin 為每個頁面間的應(yīng)用程序共享代碼創(chuàng)建 bundle。由于入口起點(diǎn)增多平斩,多頁應(yīng)用能夠復(fù)用入口起點(diǎn)之間的大量代碼/模塊亚享,從而可以極大地從這些技術(shù)中受益
const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};

3.2 輸出(output)

配置 output 選項(xiàng)可以控制 webpack 如何向硬盤寫入編譯文件。注意绘面,即使可以存在多個入口起點(diǎn)欺税,但只指定一個輸出配置。

// 單個入口起點(diǎn)
const config = {
  output: {
    filename: 'bundle.js',
    path: '/home/proj/public/assets'
  }
};
// 多個入口起點(diǎn)
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }

3.3 loader

Loaders是webpack提供的最激動人心的功能之一了揭璃。通過使用不同的loader晚凿,webpack有能力調(diào)用外部的腳本或工具,實(shí)現(xiàn)對不同格式的文件的處理瘦馍,比如說分析轉(zhuǎn)換scss為css歼秽,或者把下一代的JS文件(ES6,ES7)轉(zhuǎn)換為現(xiàn)代瀏覽器兼容的JS文件情组,對React的開發(fā)而言哲银,合適的Loaders可以把React的中用到的JSX文件轉(zhuǎn)換為JS文件扛吞。
module.rules允許你在 webpack 配置中指定多個 loader。 這是展示 loader 的一種簡明方式荆责,并且有助于使代碼變得簡潔。同時讓你對各個 loader 有個全局概覽亚脆,Loaders的配置包括以下幾方面:

  • test:一個用以匹配loaders所處理文件的拓展名的正則表達(dá)式(必須)
  • loader:loader的名稱(必須)
  • include/exclude:手動添加必須處理的文件(文件夾)或屏蔽不需要處理的文件(文件夾)(可選)做院;
  • query:為loaders提供額外的設(shè)置選項(xiàng)(可選)

load的特性

  • loader 支持鏈?zhǔn)絺鬟f。能夠?qū)Y源使用流水線(pipeline)濒持。一組鏈?zhǔn)降?loader 將按照相反的順序執(zhí)行键耕。loader 鏈中的第一個 loader 返回值給下一個 loader。在最后一個 loader柑营,返回 webpack 所預(yù)期的 JavaScript屈雄。
  • loader 可以是同步的,也可以是異步的官套。
  • loader 運(yùn)行在 Node.js 中酒奶,并且能夠執(zhí)行任何可能的操作。
  • loader 接收查詢參數(shù)奶赔。用于對 loader 傳遞配置惋嚎。
  • loader 也能夠使用 options 對象進(jìn)行配置。
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      }
  • 除了使用 package.json 常見的 main 屬性站刑,還可以將普通的 npm 模塊導(dǎo)出為 loader另伍,做法是在 package.json 里定義一個 loader 字段。
  • 插件(plugin)可以為 loader 帶來更多特性绞旅。
  • loader 能夠產(chǎn)生額外的任意文件摆尝。
    loader列表

3.4 插件(plugins)

插件(Plugins)是用來拓展Webpack功能的,它們會在整個構(gòu)建過程中生效因悲,執(zhí)行相關(guān)的任務(wù)堕汞。

  • 插件的使用
    要使用某個插件,我們需要通過npm安裝它囤捻,然后要做的就是在webpack配置中的plugins關(guān)鍵字部分添加該插件的一個實(shí)例(plugins是一個數(shù)組)臼朗。
const webpack = require('webpack');
module.exports = {
...
    module: {
        rules: [
            {
                test: /(\.jsx|\.js)$/,
                use: {
                    loader: "babel-loader"
                },
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: [
                    {
                        loader: "style-loader"
                    }, {
                        loader: "css-loader",
                        options: {
                            modules: true
                        }
                    }, {
                        loader: "postcss-loader"
                    }
                ]
            }
        ]
    },
    plugins: [
        new webpack.BannerPlugin('版權(quán)所有,翻版必究')
    ],
};
**1. HtmlWebpackPlugin插件**

這個插件的作用是依據(jù)一個簡單的index.html模板蝎土,生成一個自動引用你打包后的JS文件的新index.html视哑。

npm install --save-dev html-webpack-plugin
    plugins: [
        new HtmlWebpackPlugin({
            template: __dirname + "/app/index.html"http://new 一個這個插件的實(shí)例,并傳入相關(guān)的參數(shù)
        })
    ],
**2. Hot Module Replacement (HMR)熱加載**

它允許你在修改組件代碼后誊涯,自動刷新實(shí)時預(yù)覽修改后的效果挡毅。
3. 其他插件
- OccurenceOrderPlugin :為組件分配ID,通過這個插件webpack可以分析和優(yōu)先考慮使用最多的模塊暴构,并為它們分配最小的ID
- UglifyJsPlugin:壓縮JS代碼跪呈;
- ExtractTextPlugin:分離CSS和JS文件
4. webpack打包速度優(yōu)化

// 1.HotModuleReplacementPlugin 熱加載模塊使用
// 2.選擇一個合適的devtool屬性值 推薦:cheap-module-eval-source-map
// 3. 代碼壓縮用ParallelUglifyPlugin代替自帶的 UglifyJsPlugin插件段磨。
    // 自帶的JS壓縮插件是單線程執(zhí)行的,而[webpack-parallel-uglify-plugin](https://github.com/gdborton/webpack-parallel-uglify-plugin)可以并行的執(zhí)行
new ParallelUglifyPlugin({
           cacheDir: '.cache/',
           uglifyJS:{
             output: {
               comments: false
             },
             compress: {
               warnings: false
             }
           }
         })
// 4.CommonsChunkPlugin插件提取公共模塊
      // 提取公共模塊文件
        new webpack.optimize.CommonsChunkPlugin({
            chunks: ['home', 'detail'],
            // 開發(fā)環(huán)境下需要使用熱更新替換耗绿,而此時common用chunkhash會出錯苹支,可以直接不用hash
            filename: '[name].js' + (isProduction ? '?[chunkhash:8]' : ''),
            name: 'common'
        }),
    // 切合公共模塊的提取規(guī)則,有時后你需要明確指定默認(rèn)放到公共文件的模塊
    // 文件入口配置
    entry: {
        home: './src/js/home',
        detail: './src/js/detail',
        // 提取jquery入公共文件
        common: ['jquery', 'react', 'react-dom']
    },

更多webpack打包速度優(yōu)化參考

4. webpack使用

4.1 非配置文件命令行命令執(zhí)行

# webpack非全局安裝的情況
node_modules/.bin/webpack 入口文件 出口文件
#webpack 全局安裝情況
webpack 入口文件 出口文件

webpack 的全局安裝误阻。

# 全局安裝webpack
npm install webpack -g
# 將webpack安裝到項(xiàng)目中
npm install webpack --save-dev

4.2 webpack配置文件使用

webpack的配置文件债蜜,使用vue-cli生成的

// webpack.config.js
module.exports = {
  context: path.resolve(__dirname, '../'),
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    chunkFilename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  }
}

打包命令,可以使用npm相關(guān)配置究反,完成打包寻定,再項(xiàng)目的pakage.json文件中,對scripts對象進(jìn)行相關(guān)設(shè)置即可精耐。

{
  "name": "tapp",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "scott",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "test": "npm run unit",
    "lint": "eslint --ext .js,.vue src test/unit",
    "build": "node build/build.js" // 修改的是這里狼速,JSON文件不支持注釋,引用時請清除
  },
  "dependencies": {
    "axios": "^0.18.0",
    "babel-polyfill": "^6.26.0",
    "echarts": "^4.1.0",
  }
}

4.3 使用webpack構(gòu)建本地服務(wù)器(devServer)

如何讓你的瀏覽器監(jiān)聽你的代碼的修改卦停,并自動刷新顯示修改后的結(jié)果------熱加載
其實(shí)Webpack提供一個可選的本地開發(fā)服務(wù)器向胡,這個本地服務(wù)器基于node.js(vue-cli使用的是express)構(gòu)建,可以實(shí)現(xiàn)你想要的這些功能沫浆,不過它是一個單獨(dú)的組件捷枯,在webpack中進(jìn)行配置之前需要單獨(dú)安裝它作為項(xiàng)目依賴。(vue-cli默認(rèn)安裝了依賴)

npm install --save-dev webpack-dev-server

webpack-dev-server的配置文件

  //  devServer服務(wù)器
  devServer: {
    clientLogLevel: 'warning', // LogLevel Possible values are none, error, warning or info (default). 日志級別
   // When using the HTML5 History API, the `index.html` page will likely have to be served in place of any `404` responses专执。替換404請求的頁面
    historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    },
    hot: true, // Enable webpack's Hot Module Replacement feature 熱加載
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true, // Enable gzip compression for everything served 是否啟用壓縮
    host: HOST || config.dev.host, // url
    port: PORT || config.dev.port, // 端口
    open: config.dev.autoOpenBrowser, // 是否自動打開瀏覽器
    openPage: config.dev.openPage, // 打開瀏覽器的地址
    // 當(dāng)存在編譯器錯誤或警告時淮捆,在瀏覽器中顯示全屏覆蓋。默認(rèn)情況下禁用
    overlay: config.dev.errorOverlay
      ? { warnings: false, errors: true }
      : false,
    // 根路徑
    publicPath: config.dev.assetsPublicPath,
    // 啟用代URL
    proxy: {
     '/IntelligentWaterAffairs': {
        target: 'http://39.104.178.72:8080/', // 接口域名 //server
        changeOrigin: true, //是否跨域
      }
    },
    quiet: true, // necessary for FriendlyErrorsPlugin
    // 啟用輪詢
    watchOptions: {
      poll: config.dev.poll,
    }
  }

config/index.js 啟用devtool

    /**
     * Source Maps
     */
    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',
    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,
    cssSourceMap: true

5. Babel

  • Babel是什么本股?
    Babel其實(shí)是一個編譯JavaScript語言的平臺攀痊。
  • Babel的目的是要達(dá)到那種效果?
    1. 讓你能使用最新的JavaScript代碼(ES6拄显,ES7...)苟径,而不用管新標(biāo)準(zhǔn)是否被當(dāng)前使用的瀏覽器完全支持;
    2. 讓你能使用基于JavaScript進(jìn)行了拓展的語言躬审,比如Vue的JSX棘街;
  • Babel是怎樣配置的?
    babel的配置選項(xiàng)放在一個單獨(dú)的名為 ".babelrc" 的配置文件中承边。
  1. 安裝babel
npm install --save-dev babel-loader babel-core babel-preset-env babel-plugin-transform-runtime babel-plugin-istanbul babel-polyfill babel-preset-stage-2 babel-register
  1. babelrc文件配置
{
  "presets": [
    ["env", { "modules": false }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"],
  "comments": false,
  "env": {
    "test": {
      "presets": ["env", "stage-2"],
      "plugins": [ "istanbul" ]
    }
  }
}

3.webpack.config.js 配置

      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },

參考資料: 部分內(nèi)容來源于參考資料遭殉。
https://www.webpackjs.com/concepts/
https://segmentfault.com/a/1190000006178770#articleHeader5

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市博助,隨后出現(xiàn)的幾起案子险污,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛔糯,死亡現(xiàn)場離奇詭異拯腮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蚁飒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門动壤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人飒箭,你說我怎么就攤上這事狼电。” “怎么了弦蹂?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長强窖。 經(jīng)常有香客問我凸椿,道長,這世上最難降的妖魔是什么翅溺? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任脑漫,我火速辦了婚禮,結(jié)果婚禮上咙崎,老公的妹妹穿的比我還像新娘优幸。我一直安慰自己,他們只是感情好褪猛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布网杆。 她就那樣靜靜地躺著,像睡著了一般伊滋。 火紅的嫁衣襯著肌膚如雪碳却。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天笑旺,我揣著相機(jī)與錄音昼浦,去河邊找鬼。 笑死筒主,一個胖子當(dāng)著我的面吹牛关噪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乌妙,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼使兔,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冠胯?” 一聲冷哼從身側(cè)響起火诸,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎荠察,沒想到半個月后置蜀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奈搜,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年盯荤,在試婚紗的時候發(fā)現(xiàn)自己被綠了馋吗。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡秋秤,死狀恐怖宏粤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情灼卢,我是刑警寧澤绍哎,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站鞋真,受9級特大地震影響崇堰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涩咖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一海诲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧檩互,春花似錦特幔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至零院,卻和暖如春溉跃,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背告抄。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工撰茎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人打洼。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓龄糊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親募疮。 傳聞我的和親對象是個殘疾皇子炫惩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容