npm package diff
Package: @forge/bundler
Versions: 6.1.2-next.1 - 6.1.2-next.0-experimental-8a53773
File: package/out/webpack.js
Index: package/out/webpack.js
===================================================================
--- package/out/webpack.js
+++ package/out/webpack.js
@@ -1,11 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WebpackBundler = exports.getCompiler = exports.handleWebpackCompilationResult = void 0;
const tslib_1 = require("tslib");
+const fs_1 = require("fs");
+const path_1 = tslib_1.__importDefault(require("path"));
+const parser = tslib_1.__importStar(require("@babel/parser"));
+const traverse_1 = tslib_1.__importDefault(require("@babel/traverse"));
const webpack_1 = tslib_1.__importDefault(require("webpack"));
const cli_shared_1 = require("@forge/cli-shared");
const text_1 = require("./text");
+const types_1 = require("./types");
function handleWebpackCompilationResult(logger, err, stats) {
if (err) {
throw err;
}
@@ -35,38 +40,113 @@
function getCompiler(config) {
return (0, webpack_1.default)(config);
}
exports.getCompiler = getCompiler;
-function getNodeModuleNames(stats) {
- const { modules } = stats.toJson({ modules: true });
- if (modules) {
- const filteredModuleNames = new Set();
- modules
- .map((m) => m.name || '')
- .forEach((name) => {
- const parts = name.match(/^\.\/node_modules\/([^/]+)\/([^/]+)/);
- if (parts) {
- const module = parts[1][0] === '@' ? `${parts[1]}/${parts[2]}` : parts[1];
- filteredModuleNames.add(module);
+function moduleFromPath(name) {
+ const depMatch = name.match(/^\.\/node_modules\/([^/]+)\/([^/]+)/);
+ if (depMatch) {
+ const moduleName = depMatch[1][0] === '@' ? `${depMatch[1]}/${depMatch[2]}` : depMatch[1];
+ return { type: 'dependency', package: moduleName };
+ }
+ const externalMatch = name.match(/^external "(?:node:)?([^:"]+)"$/);
+ if (externalMatch) {
+ return { type: 'dependency', package: externalMatch[1].split('/')[0] };
+ }
+ if (name.startsWith('webpack/runtime/')) {
+ return { type: 'internal' };
+ }
+ if (!name.includes('.js') && !name.includes('.ts')) {
+ throw new Error(`Unknown module type for ${JSON.stringify(name)}.`);
+ }
+ return { type: 'local', path: name };
+}
+function processModule(metadata, module) {
+ if (module.modules) {
+ for (const subModule of module.modules) {
+ processModule(metadata, subModule);
+ }
+ return;
+ }
+ if (!module.name) {
+ throw new Error('Module name is missing');
+ }
+ const packedModule = moduleFromPath(module.name);
+ const issuerModule = module.issuerName ? moduleFromPath(module.issuerName) : undefined;
+ if (packedModule.type === 'local') {
+ const ext = path_1.default.extname(packedModule.path);
+ if (ext.match(/^\.[cm]?jsx?$/)) {
+ metadata.jsFiles++;
+ }
+ else if (ext.match(/^\.[cm]?tsx?$/)) {
+ metadata.tsFiles++;
+ }
+ else if (ext === '.json') {
+ return;
+ }
+ const source = (0, fs_1.readFileSync)(packedModule.path, 'utf8');
+ const ast = parser.parse(source, {
+ sourceType: 'module',
+ plugins: ['typescript', 'jsx']
+ });
+ (0, traverse_1.default)(ast, {
+ ImportDeclaration: (path) => {
+ let from = path.node.source.value;
+ if (from.startsWith('@forge/')) {
+ from = from.replace('@forge/', '');
+ for (const specifier of path.node.specifiers) {
+ let member;
+ switch (specifier.type) {
+ case 'ImportDefaultSpecifier':
+ member = specifier.local.name;
+ break;
+ case 'ImportNamespaceSpecifier':
+ member = specifier.local.name;
+ break;
+ case 'ImportSpecifier':
+ switch (specifier.imported.type) {
+ case 'Identifier':
+ member = specifier.imported.name;
+ break;
+ case 'StringLiteral':
+ member = specifier.imported.value;
+ break;
+ }
+ }
+ metadata.sdkImports.add(`${from}.${member}`);
+ }
+ }
}
- else if (name.includes('unsupported.js')) {
- filteredModuleNames.add(name.slice(name.indexOf('?')));
- }
});
- return Array.from(filteredModuleNames);
}
+ if (issuerModule?.type === 'local' && packedModule.type === 'dependency') {
+ metadata.dependencies.add(packedModule.package);
+ }
}
+function getMetadata(stats) {
+ const { modules } = stats.toJson({ modules: true });
+ const metadata = (0, types_1.emptyMetadata)();
+ for (const module of modules ?? []) {
+ processModule(metadata, module);
+ }
+ let packageJson;
+ try {
+ const packageFile = (0, fs_1.readFileSync)('package.json', 'utf8');
+ packageJson = JSON.parse(packageFile);
+ }
+ catch { }
+ if (packageJson?.type === 'module') {
+ metadata.esm = true;
+ }
+ return metadata;
+}
class WebpackBundler {
logger;
constructor(logger) {
this.logger = logger;
}
async getOutput(config, stats) {
const outputDir = config.output.path;
- const metadata = {};
- if (stats) {
- metadata.modules = getNodeModuleNames(stats);
- }
+ const metadata = getMetadata(stats);
return { outputDir, metadata };
}
async runCompiler(config) {
const compiler = getCompiler(config);