Как добавить глобальную переменную времени компиляции в webpack?

1

У меня есть динамически настраиваемая настройка веб-пакета с некоторыми пользовательскими загрузчиками. Каждому из этих загрузчиков нужен объект конфигурации, который известен только динамически, во время компиляции, поэтому его невозможно записать в options загрузчика. Как загрузчики могут получить доступ к этому объекту? Есть ли "канонический" способ иметь глобальный компилятор в webpack?

В принципе, моя настройка позволяет использовать несколько динамических конфигураций времени сборки, она выглядит так:

// webpack.config.js

let defaults = {
   ....
    module: {
        loaders: [
            {
                test: '.some.special.stuff',
                loader: 'my-own-loader',
            }
}

module.exports = function main() {
    let BUILD_CONFIG = require(process.env.BUILD_CONFIG);  
    ....
    return defaults;
}

Таким образом, веб-пакет должен быть вызван как BUILD_CONFIG=some-config.js webpack. Обратите внимание, что some-config.js содержит много материалов, не относящихся к веб-папке, поэтому я не могу просто вернуть его из main или объединить с defaults

Теперь у меня есть my-own-loader в my-own-loader.js:

// my-own-loader.js

module.exports = function main(content) {
  ...

Мой вопрос заключается в том, как получить доступ к этой BUILD_CONFIG переменной из WebPack main в загрузчике main.

  • 0
    Я не очень ясно, где вы хотите использовать переменную, но вы пытаетесь сделать что-то похожее на то, что переменные среды в WebPack выполняет?
  • 0
    @zero298: zero298: да, но как я могу получить к нему доступ из загрузчика?
Показать ещё 1 комментарий
Теги:
webpack

1 ответ

2
Лучший ответ

Я думаю, что понимаю, что вы пытаетесь сделать, и иметь примерный проект, описывающий процесс.

Чтобы начать, я собираюсь установить переменную среды с именем TEST_VAR через любой механизм, поддерживаемый моей платформой. Я нахожусь на macOS, чтобы export TEST_VAR=fizzbuzz. Мой loader.js может использовать эту переменную среды через соглашение узла: process.env.TEST_VAR.

Помните, что ваш webpack.config.js по-прежнему является файлом JavaScript с запуском узла. Вы можете использовать все встроенные модули, поддерживающие этот узел, включая process.env.

Рассмотрим следующие файлы и структуру:

Состав

webpack-test
|- package.json
|- webpack.config.js
|- index.html
|- /dist
  |- bundle.js
|- /loaders
  | obj-loader.js
|- /res
  |- /obj
    |- dummy.obj
|- /src
  |- index.js

package.json

{
  "name": "webpack-test",
  "version": "0.0.1",
  "main": "index.js",
  "dependencies": {
    "webpack": "^3.8.1"
  },
  "devDependencies": {
    "http-server": "^0.10.0",
    "loader-utils": "^1.1.0",
  },
  "scripts": {
    "start": "http-server .",
    "build": "webpack",
  },
}

webpack.config.js

const path = require("path");

module.exports = {
    entry: "./src/index.js",
    output: {
        filename: "bundle.js",
        path: path.resolve(__dirname, "dist")
    },
    resolveLoader: {
        modules: [
            path.resolve(__dirname, "loaders")
        ]
    },
    module: {
        rules: [
            {
                test: /\.obj$/,
                use: {
                    loader: "obj-loader",
                    options: {
                        dummyText: "lorem ipsum"
                    }
                }
            }
        ]
    }
};

/loaders/obj-loader.js

const loaderUtils = require("loader-utils"),
    schemaUtils = require("schema-utils");

function loader(source) {
    const options = loaderUtils.getOptions(this);
    console.log(options);

    let tmp = process.env.TEST_VAR;
    if (tmp === undefined) {
        console.warn("TEST_VAR is not defined");
    }
    return 'export default function(){return "TEST_VAR: ${tmp} || ${source} || ${options.dummyText}";}';
}

module.exports = loader;

/res/obj/dummy.obj

Hello

/src/index.js

import dummy from "../res/obj/dummy.obj";

(function () {
    "use strict";

    function main() {
        document.querySelector("p").innerHTML = dummy();
    }
    document.addEventListener("DOMContentLoaded", main);
}());

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Webpack Test</title>
    <script src="dist/bundle.js"></script>
</head>
<bod>
    <main>
        <h1>Webpack Test</h1>
        <p>Lorem Ipsum</p>
    </main>
</bod>

</html>

Всякий раз, когда я создаю и запускаю эту веб-страницу, я получаю то, что составляет:

<main>
    <h1>Webpack Test</h1>
    <p>TEST_VAR: fizzbuzz || Hello || lorem ipsum</p>
</main>

Где "fizzbuzz" было добавлено из переменной среды "Hello", источник находится в /res/obj/dummy.obj, а "lorem ipsum" - это текст, который я указал как параметр dummyText для obj-loader. Однако он мог бы так же легко получить переменную окружения, которую я установил.


Дополнительное обновление на основе редактирования

Учитывая ваше редактирование, что с этим делать; вместо того, чтобы устанавливать правило по defaults установите его в экспортируемой функции, чтобы получить доступ к области. Затем добавьте правила загрузчика на основе нового синтаксиса правила: module.loaders теперь module.rules. Таким образом, у вас есть доступ к options в вашем пользовательском загрузчике и, следовательно, у вас есть доступ к BUILD_CONFIG.

Более новый webpack.config.js

// Hypothetically you run:
// export BUILD_CONFIG=some-config.js
// Which sets:
// process.env.BUILD_CONFIG = "some-config.js";

// New Webpack loader/rules syntax
// https://webpack.js.org/guides/migrating/#module-loaders-is-now-module-rules
let defaults = {
    module: {
        rules: [
            /*
             *Set this later in exported function
            {
                test: ".some.special.stuff",
                use: {
                    loader: "my-own-loader",
                    options: {
                        some: "options"
                    }
                }
            }
             */
        ]
    }
};

module.exports = function (content) {
    let BUILD_CONFIG = require(process.env.BUILD_CONFIG);    
    // Other code

    let dd = defaults;
    defaults.module.rules.push({
        test: ".some.special.stuff",
        use: {
            loader: "my-own-loader",
            options: {
                stuffFromEnvConfig: BUILD_CONFIG
            }
        }
    });

    return dd;
};

мой-собственный loader.js

const loaderUtils = require("loader-utils"),
    schemaUtils = require("schema-utils");

module.exports = function main(content) {
    const options = loaderUtils.getOptions(this);
    console.log(options);

    let tmp;
    if (options.stuffFromEnvConfig.useFirst) {
        tmp = "Fizz";
    } else {
        tmp = "Buzz";
    }

    return 'export default function(){return "TEST_VAR: ${tmp}";}';
};
  • 0
    Спасибо за это, к сожалению, моя конфигурация времени сборки - это не просто переменные env, поэтому я не могу присоединить ее к process.env .
  • 0
    @georg Можете ли вы рассказать подробнее? Я действительно не совсем понимаю вашу конфигурацию.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню