Webpack - JS -自定义dist文件夹结构



我需要帮助我的webpack配置。

目前,我有一个共同的项目,将服务于多个网站。

默认情况下,模板位于这里:jspagesXXX.js

如果在此位置找到覆盖文件:jspagesoverridesSiteNameXXX.js具有相同的js名称,我将使用覆盖文件。

目前,这正在工作。我能够生成所有的入口点与覆盖/默认js (cf下面的代码)。

我不能做的

在dist文件夹内,我想根据网站名称创建一个不同的文件夹架构。这是我想要实现的

dist

  • home.js(默认为所有不同的网站)
  • site2
    • home.js
  • site5
    • home.js

代码

module.exports = {
mode: "development",
devtool: "source-map",
entry: {
home: [
XXXsrcmainresourcesstaticjspageshome.js',    
],
home_site2: [
XXXsrcmainresourcesstaticjspagesoverridessite2home.js',
],
home_site5: [
XXXsrcmainresourcesstaticjspagesoverridessite5home.js',
]
},
output: {
filename: "[name].js",
path: resolvePath.dist,
publicPath: resolvePath.publicPath
}
}

注意:我可以通过使用规则

在css中执行它任何帮助将是感激的,由于

TLDR;

你可以在这个StackBlitz应用程序中找到一个工作示例。


让我们从配置文件开始:

webpack.config.js

const path = require('path');
// We're doing this import so that we can get autocompletion.
/**
* @type {import("webpack/types").Configuration}
*/
const config = {
entry: {
home: path.join(__dirname, 'src', 'home.js'),
home_site2: path.join(__dirname, 'src/overrides/site2', 'home.js'),
home_site5: path.join(__dirname, 'src/overrides/site5', 'home.js')
},
output: {
path: path.join(__dirname, 'dist'),
filename: fileData => {
const { chunk } = fileData;
if (!chunk.entryModule) {
return crtPath;
}
const { userRequest: req } = chunk.entryModule;
const siteNameDelimiter = 'overrides/';
if (req.includes(siteNameDelimiter)) {
fileData.chunk = null;
fileData.filename = req.slice(
req.indexOf(siteNameDelimiter) + siteNameDelimiter.length
);
return '[path][name].js';
}
return '[name].js';
},
// Emit fresh files every time.
clean: true
},
mode: 'development'
};
module.exports = config;
首先,重要的是要提到entry对象中的每个项都将导致一个新的。。这就是为什么在捆绑过程结束时,将有3个文件。
让我们来澄清一下什么是是多少。一个块可以被认为是一组模块。与条目项相关联的块可以称为主块。还有其他类型的块,例如,当您使用import()函数时,将创建一个新的块。然而,主块与其他块的区别在于它有webpack注入的代码,也称为运行时代码。这些额外的代码负责惰性加载其他块,处理块的加载等等。其他块也有一些运行时代码,但与主块的数量相比太少了。

在打包过程结束时,块资产创建。通过资产,它意味着块的结果文件,其中还包含所有必要的代码。这部分也是确定块的最终路径的地方。

发生在TemplatedPathPlugin.js文件中。这里我们还可以看到可用的占位符:

const replacePathVariables = (path, data, assetInfo) => {
/* ... */

// Filename context
//
// Placeholders
//
// for /some/path/file.js?query#fragment:
// [file] - /some/path/file.js
// [query] - ?query
// [fragment] - #fragment
// [base] - file.js
// [path] - /some/path/
// [name] - file
// [ext] - .js
if (typeof data.filename === "string") { /* ... */ }
// Compilation context
/* ... */
// Chunk context
/* ... */
}

就目前情况而言,Filename context部分是我们感兴趣的部分。

下面是output选项的配置:
output: {
path: path.join(__dirname, 'dist'),
filename: fileData => {
const { chunk } = fileData;
if (!chunk.entryModule) {
return crtPath;
}
const { userRequest: req } = chunk.entryModule;
const siteNameDelimiter = 'overrides/';
if (req.includes(siteNameDelimiter)) {
fileData.chunk = null;
fileData.filename = req.slice(
req.indexOf(siteNameDelimiter) + siteNameDelimiter.length
);
return '[path][name].js';
}
return '[name].js';
},
// Emit fresh files every time.
clean: true
},

注意output.filename不再是一个字符串值,而是一个函数。在考虑TemplatedPathPlugin的逻辑之前立即调用该函数。因此,在初始文件位于overrides目录下的情况下,生成的块路径将是这样的形式:

/* ... */
// [base] - file.js
// [path] - /some/path/
// [name] - file
/* ... */
const siteNameDelimiter = 'overrides/';
if (req.includes(siteNameDelimiter)) {
fileData.chunk = null;
fileData.filename = req.slice(
req.indexOf(siteNameDelimiter) + siteNameDelimiter.length
);
return '[path][name].js';
}
/* ... *

在本例中,path是在入口路径中overrides/之后的内容,而名称是指最后一个/.js之间的内容。
例如,在src/overrides/site2/home.js,path = site2/name = home中,因此'[path][name].js' = 'site2/home'.

现在另一个重要的方面:无论返回的路径是什么(例如'home.js','site2/home'),它将被附加到output.path的值,在本例中指的是:

path.join(__dirname, 'dist'),

那么,块的最终路径是:

  • 家→dist/home.js
  • home_site2→dist/site2/home.js
  • home_site5→dist/site5/home.js

最新更新