webpack 自動發現 entry 的配置和引用方式


假定我們的項目目錄為如下的樣子:

- root/
    - assets/
        - app/
            - global.js
            - index/
                - index.js
            - auth/
                - login.js
                - register.js
                - ...
        - webpack.config.js
    - public/
        - assets/
            - build/

使用如下的 webpack 配置:

var webpack = require('webpack');
var fs = require('fs');
var path = require('path');
var glob = require('glob');

const debug = process.env.NODE_ENV !== 'production';

function entries (globPath) {
    var files = glob.sync(globPath);
    var entries = {}, entry, dirname, basename;

    for (var i = 0; i < files.length; i++) {
        entry = files[i];
        dirname = path.dirname(entry);
        basename = path.basename(entry, '.js');
        entries[path.join(dirname, basename)] = './' + entry;
    }

    return entries;
}

module.exports = {
    entry: entries('app/**/*.js'),
    output: {
        path: path.join(__dirname, '..', 'public', 'assets', 'build'),
        publicPath: '/assets/build/',
        filename: '[name]' + (debug ? '' : '-[chunkhash]') + '.js',
        chunkFilename: '[id]' + (debug ? '' : '-[chunkhash]') + '.js'
    },
    plugins: [
        function () {
            this.plugin('done', function (stats) {
                stats = stats.compilation.getStats().toJson({
                    hash: true,
                    publicPath: true,
                    assets: true,
                    chunks: false,
                    modules: false,
                    source: false,
                    errorDetails: false,
                    timings: false
                });

                var json = {}, chunk;
                for (var key in stats.assetsByChunkName) {
                    if (stats.assetsByChunkName.hasOwnProperty(key)) {
                        chunk = stats.assetsByChunkName[key];
                        json[key + '.js'] = chunk[0];
                    }
                }

                fs.writeFileSync(
                    path.join(__dirname, '..', 'public', 'assets', 'build', 'rev-manifest.json'),
                    JSON.stringify(json, null, 2)
                );
            });
        }
    ]
};

這樣,我們就可以得到形如這樣的構建輸出:

- root/
    - assets/
        - ...
    - public/
        - assets/
            - build/
                - rev-manifest.json
                - app/
                    - global.js
                - auth/
                    - login.js
                    - register.js
                    - ...

意義何在???

關鍵在於 rev-manifest.json 文件,我們查看一下文件內容:

{
  "app/global.js": "app/global.js",
  "app/index/index.js": "app/index/index.js",
  "app/auth/login.js": "app/auth/login.js",
  "app/auth/register.js": "app/auth/register.js",
}

意義何在???

好吧,我們再看一下在生產環境下的構建輸出:

{
  "app/global.js": "app/global-6ff91e44b26765ae797a.js",
  "app/index/index.js": "app/index/index-d294c62e36a91fa7237d.js",
  "app/auth/login.js": "app/auth/login-f04b1d5a3cffac4d70aa.js",
  "app/auth/register.js": "app/auth/register-502d794e8e0c7f1a230d.js",
}

如果配合模板中的函數:

<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="{{ assets_url('app/index/index.js') }}"></script>
</head>
<body>
</body>
</html>

assets_url 函數可以直接獲取 rev-manifest.json 內容,根據給定的 key 得到對應的構建文件的可訪問路徑,自動的根據不同的環境獲取到正確的引用結果。

同時,我們可以在源代碼目錄里面,根據需求對代碼進行模塊化管理,構建出來的代碼結構會和我們源代碼中管理的一致。

這樣一來,既可以享受構建系統的優勢,又無需在新增或修改模塊時改動 webpack.config.js,是不是很方便呢?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM