我正在使用 Webpack 构建一个应用程序,除其他外,还需要它发出用于 PWA 目的的 manifest.json 文件。我希望它是动态构建的,这样它就可以获得图标的正确资源 URL(理想情况下,它会包含在构建中),并且可能从其他文件中读取值(例如从 package.json 中读取描述)。我见过一些允许转换 JSON 文件的插件,但它们似乎是用于分配静态值而不是对其他文件的引用。我是否只需要为此构建一个完整的自定义插件或加载器?
Soooo,我找到了一种方法来做到这一点,但这似乎不是正确的解决方案...我构建了一个manifest.json.ts文件,我已将其设置为通过ts-loader和自定义运行加载器在构建时解析并构建 json,并最终在根目录中设置为资源资产。
manifest.json.ts
import * as pkg from "/package.json";
import * as favIcon from "../static/images/favicon.ico";
import * as icon192 from "../static/images/icon-192.png";
import * as icon512 from "../static/images/icon-512.png";
import * as icon192Maskable from "../static/images/icon-192-maskable.png";
import * as icon512Maskable from "../static/images/icon-512-maskable.png";
export default {
"$schema": "https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/web-manifest.json",
"name": pkg?.title,
"short_name": pkg?.acronym,
"description": pkg?.description,
"theme_color": "#33557c",
"background_color": "#FFFFFF",
"display": "standalone",
"id": "/",
"start_url": "/",
"scope": "/",
"icons": [
{ "src": favIcon, "type": "image/x-icon", "sizes": "32x32" },
{ "src": icon192, "type": "image/png", "sizes": "192x192" },
{ "src": icon512, "type": "image/png", "sizes": "512x512" },
{ "src": icon192Maskable, "type": "image/png", "sizes": "192x192", "purpose": "maskable" },
{ "src": icon512Maskable, "type": "image/png", "sizes": "512x512", "purpose": "maskable" }
]
};
json-js-loader.js:
const scriptExtensionRemovalReg = /\.[cm]?[tj]s(\?.*)?$/i;
function getFileName(resourcePath) {
return resourcePath.split(/[\/\\]/).pop();
}
module.exports.pitch = async function(remaining) {
const targetResource = `${this.resourcePath}.webpack[javascript/auto]!=!${remaining}`;
const result = await this.importModule(targetResource);
const resultContent = JSON.stringify(result?.default || result);
this._module.matchResource = getFileName(this.resourcePath).replace(scriptExtensionRemovalReg, "");
this.resourcePath = this.resourcePath.replace(scriptExtensionRemovalReg, "");
return resultContent;
}
webpack.config.js:
//omitting previous loaders...
{
test: /\.json\.[cm]?[tj]s$/i,
type: "asset/resource",
generator: {
filename: "[hash][ext][query]"
},
use: [
path.resolve(__dirname, "build/json-js-loader.js"),
{
loader: "ts-loader",
options: {
compilerOptions: {
module: "CommonJS",
rootDir: appFolder
}
}
}
]
}
我还必须修改我的主打字稿加载器以排除 .json.ts 文件。