我有一个动态可配置的webpack设置,带有一些自定义加载器。这些加载器中的每一个都需要一个配置对象,该对象在编译时是动态已知的,因此无法在加载器的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;
}
所以webpack应该被称为BUILD_CONFIG=some-config.js webpack
。请注意,some-config.js
包含许多非webpack内容,因此我不能仅从main
返回它或将其与defaults
合并
现在,我在my-own-loader
中有my-own-loader.js
:
// my-own-loader.js
module.exports = function main(content) {
...
我的问题是如何从加载程序BUILD_CONFIG
中的webpack main
访问main
变量。
答案 0 :(得分: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
{
"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",
},
}
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"
}
}
}
]
}
};
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;
Hello
import dummy from "../res/obj/dummy.obj";
(function () {
"use strict";
function main() {
document.querySelector("p").innerHTML = dummy();
}
document.addEventListener("DOMContentLoaded", main);
}());
<!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
选项指定的文本1}}。但是,它可能很容易来自我设置的环境变量。
基于修改的其他更新
考虑到你的编辑,这个怎么样;而不是在obj-loader
中设置规则,而是在导出的函数中设置它以获得范围访问权限。然后根据新规则语法添加加载程序规则:module.loaders
is now module.rules
。这样,您就可以在自定义加载器中访问defaults
,从而可以访问options
。
BUILD_CONFIG
// 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;
};