@lingui/cli
Version:
Lingui CLI to extract messages, compile catalogs, and manage translation workflows
104 lines (103 loc) • 4.68 kB
JavaScript
import path from "path";
import { buildIncludeDepsFilter } from "../buildIncludeDepsFilter.js";
import { DEFAULT_EXCLUDE_EXTENSIONS } from "../constants.js";
import { buildContentFilterRe } from "../buildContentFilter.js";
import linguiMacroPlugin from "@lingui/babel-plugin-lingui-macro";
import { transformAsync } from "@babel/core";
import { getBabelParserOptions } from "../../api/extractors/babel.js";
function createExtRegExp(extensions) {
return new RegExp("\\.(?:" + extensions.join("|") + ")(?:\\?.*)?$");
}
export function createRolldownBundler(options) {
return {
async bundle(entryPoints, outDir, linguiConfig) {
let rolldown;
try {
rolldown = await import("rolldown");
}
catch {
throw new Error(`"rolldown" is required for createRolldownBundler but is not installed. ` +
`Install it with: npm install rolldown`);
}
const includeDeps = options?.includeDeps || [];
const excludeExtensions = options?.excludeExtensions || DEFAULT_EXCLUDE_EXTENSIONS;
const shouldInclude = buildIncludeDepsFilter(includeDeps);
const extRegExp = createExtRegExp(excludeExtensions);
const hasMacroRe = buildContentFilterRe(linguiConfig);
const macroPlugin = {
name: "lingui:macro-transform",
transform: {
filter: {
id: /\.(?:[jt]sx?|[cm][jt]s)(?:$|\?)/,
code: hasMacroRe,
},
handler: async (code, filename, meta) => {
const result = await transformAsync(code, {
babelrc: false,
configFile: false,
filename,
sourceMaps: true,
parserOpts: {
plugins: getBabelParserOptions(filename, {}),
},
plugins: [
[
linguiMacroPlugin,
{
descriptorFields: "all",
linguiConfig,
},
],
],
});
return { code: result?.code ?? undefined, map: result?.map };
},
},
};
let rolldownOptions = {
input: entryPoints,
output: {
dir: outDir,
format: "esm",
sourcemap: "inline",
entryFileNames: "[name].jsx",
sourcemapPathTransform: (relativeSourcePath, sourcemapPath) => {
const sourcemapDir = path.dirname(sourcemapPath);
const absoluteSource = path.resolve(sourcemapDir, relativeSourcePath);
return path.relative(process.cwd(), absoluteSource);
},
},
platform: "node",
treeshake: true,
transform: {
jsx: "preserve",
},
external: (id, importer) => {
if (extRegExp.test(id)) {
return true;
}
if (importer && !path.isAbsolute(id) && /^[^.#/]/.test(id)) {
return !shouldInclude(id);
}
return false;
},
plugins: [macroPlugin],
};
if (options?.resolveRolldownOptions) {
rolldownOptions = options.resolveRolldownOptions(rolldownOptions);
}
const result = await rolldown.build(rolldownOptions);
const outputChunks = result.output.filter((item) => item.type === "chunk");
const outputFileNames = new Set(outputChunks.map((c) => c.fileName));
const chunks = outputChunks.map((chunk) => ({
id: chunk.fileName,
filePath: path.join(outDir, chunk.fileName),
entryPoint: chunk.isEntry && chunk.facadeModuleId
? chunk.facadeModuleId.replace(/\\/g, "/")
: undefined,
imports: [...chunk.imports, ...chunk.dynamicImports].filter((imp) => outputFileNames.has(imp)),
}));
return { chunks };
},
};
}