Fix legacy build

The build process failed because webpack does not allow failed imports
when it is run as a module.
This detects modules with default exports and only generates import
statements for default exports where they are available.
This commit is contained in:
Maximilian Krög
2021-05-02 23:18:19 +02:00
parent 8ff40c40e8
commit 40f8e69675
12 changed files with 77 additions and 63 deletions

View File

@@ -14,12 +14,13 @@
] ]
}, },
"plugins": [ "plugins": [
"config/jsdoc/api/plugins/markdown.cjs", "config/jsdoc/plugins/markdown.cjs",
"jsdoc-plugin-typescript", "jsdoc-plugin-typescript",
"config/jsdoc/api/plugins/inline-options.cjs", "config/jsdoc/plugins/inline-options.cjs",
"config/jsdoc/api/plugins/events.cjs", "config/jsdoc/plugins/events.cjs",
"config/jsdoc/api/plugins/observable.cjs", "config/jsdoc/plugins/observable.cjs",
"config/jsdoc/api/plugins/api.cjs" "config/jsdoc/plugins/api.cjs",
"config/jsdoc/plugins/default-export.cjs"
], ],
"typescript": { "typescript": {
"moduleRoot": "src" "moduleRoot": "src"

View File

@@ -11,8 +11,9 @@
}, },
"plugins": [ "plugins": [
"jsdoc-plugin-typescript", "jsdoc-plugin-typescript",
"config/jsdoc/info/define-plugin.cjs", "config/jsdoc/plugins/define-plugin.cjs",
"config/jsdoc/info/virtual-plugin.cjs" "config/jsdoc/plugins/virtual-plugin.cjs",
"config/jsdoc/plugins/default-export.cjs"
], ],
"typescript": { "typescript": {
"moduleRoot": "src" "moduleRoot": "src"

View File

@@ -137,6 +137,9 @@ exports.publish = function (data, opts) {
return true; return true;
}); });
} }
if (doc.isDefaultExport) {
symbol.isDefaultExport = true;
}
const target = isExterns ? externs : symbols; const target = isExterns ? externs : symbols;
const existingSymbol = symbolsByName[symbol.name]; const existingSymbol = symbolsByName[symbol.name];

View File

@@ -104,26 +104,6 @@ function includeTypes(doclet) {
} }
} }
const defaultExports = {};
const path = require('path');
const moduleRoot = path.join(process.cwd(), 'src');
// Tag default exported Identifiers because their name should be the same as the module name.
exports.astNodeVisitor = {
visitNode: function (node, e, parser, currentSourceName) {
if (node.parent && node.parent.type === 'ExportDefaultDeclaration') {
const modulePath = path
.relative(moduleRoot, currentSourceName)
.replace(/\.js$/, '');
const exportName =
'module:' +
modulePath.replace(/\\/g, '/') +
(node.name ? '~' + node.name : '');
defaultExports[exportName] = true;
}
},
};
function sortOtherMembers(doclet) { function sortOtherMembers(doclet) {
if (doclet.fires) { if (doclet.fires) {
doclet.fires.sort(function (a, b) { doclet.fires.sort(function (a, b) {
@@ -198,18 +178,4 @@ exports.handlers = {
} }
} }
}, },
processingComplete(e) {
const byLongname = e.doclets.index.longname;
for (const name in defaultExports) {
if (!(name in byLongname)) {
throw new Error(
`missing ${name} in doclet index, did you forget a @module tag?`
);
}
byLongname[name].forEach(function (doclet) {
doclet.isDefaultExport = true;
});
}
},
}; };

View File

@@ -0,0 +1,35 @@
const defaultExports = {};
const path = require('path');
const moduleRoot = path.join(process.cwd(), 'src');
// Tag default exported Identifiers because their name should be the same as the module name.
exports.astNodeVisitor = {
visitNode: function (node, e, parser, currentSourceName) {
if (node.parent && node.parent.type === 'ExportDefaultDeclaration') {
const modulePath = path
.relative(moduleRoot, currentSourceName)
.replace(/\.js$/, '');
const exportName =
'module:' +
modulePath.replace(/\\/g, '/') +
(node.name ? '~' + node.name : '');
defaultExports[exportName] = true;
}
},
};
exports.handlers = {
processingComplete(e) {
const byLongname = e.doclets.index.longname;
for (const name in defaultExports) {
if (!(name in byLongname)) {
throw new Error(
`missing ${name} in doclet index, did you forget a @module tag?`
);
}
byLongname[name].forEach(function (doclet) {
doclet.isDefaultExport = true;
});
}
},
};

View File

@@ -22,15 +22,20 @@ async function getSymbols() {
*/ */
function getImport(symbol, member) { function getImport(symbol, member) {
const defaultExport = symbol.name.split('~'); const defaultExport = symbol.name.split('~');
const namedExport = symbol.name.split('.'); if (symbol.isDefaultExport) {
if (defaultExport.length > 1 && defaultExport[0].indexOf('.') === -1) { const from = defaultExport[0].replace(/^module\:/, './');
const from = defaultExport[0].replace(/^module\:/, './') + '.js';
const importName = from.replace(/[.\/]+/g, '$'); const importName = from.replace(/[.\/]+/g, '$');
return `import ${importName} from '${from}';`; return `import ${importName} from '${from}.js';`;
} else if (namedExport.length > 1 && member) { }
const from = namedExport[0].replace(/^module\:/, './') + '.js'; const namedExport = symbol.name.split('.');
if (
member &&
namedExport.length > 1 &&
(defaultExport.length <= 1 || defaultExport[0].indexOf('.') !== -1)
) {
const from = namedExport[0].replace(/^module\:/, './');
const importName = from.replace(/[.\/]+/g, '_'); const importName = from.replace(/[.\/]+/g, '_');
return `import {${member} as ${importName}$${member}} from '${from}';`; return `import {${member} as ${importName}$${member}} from '${from}.js';`;
} }
} }
@@ -44,9 +49,11 @@ function getImport(symbol, member) {
function formatSymbolExport(symbol, namespaces, imports) { function formatSymbolExport(symbol, namespaces, imports) {
const name = symbol.name; const name = symbol.name;
const parts = name.split('~'); const parts = name.split('~');
const isNamed = parts[0].indexOf('.') !== -1;
const nsParts = parts[0].replace(/^module\:/, '').split(/[\/\.]/); const nsParts = parts[0].replace(/^module\:/, '').split(/[\/\.]/);
const last = nsParts.length - 1; const last = nsParts.length - 1;
const imp = getImport(symbol, nsParts[last]);
if (imp) {
const isNamed = parts[0].indexOf('.') !== -1;
const importName = isNamed const importName = isNamed
? '_' + nsParts.slice(0, last).join('_') + '$' + nsParts[last] ? '_' + nsParts.slice(0, last).join('_') + '$' + nsParts[last]
: '$' + nsParts.join('$'); : '$' + nsParts.join('$');
@@ -56,12 +63,10 @@ function formatSymbolExport(symbol, namespaces, imports) {
namespaces[line] = namespaces[line] =
(line in namespaces ? namespaces[line] : true) && i < ii - 1; (line in namespaces ? namespaces[line] : true) && i < ii - 1;
} }
line += ` = ${importName} || {};`; line += ` = ${importName};`;
const imp = getImport(symbol, nsParts.pop());
if (imp) {
imports[imp] = true; imports[imp] = true;
}
return line; return line;
}
} }
/** /**
@@ -71,7 +76,7 @@ function formatSymbolExport(symbol, namespaces, imports) {
*/ */
function generateExports(symbols) { function generateExports(symbols) {
const namespaces = {}; const namespaces = {};
const imports = []; const imports = {};
const blocks = []; const blocks = [];
symbols.forEach(function (symbol) { symbols.forEach(function (symbol) {
const name = symbol.name; const name = symbol.name;
@@ -80,7 +85,10 @@ function generateExports(symbols) {
if (imp) { if (imp) {
imports[imp] = true; imports[imp] = true;
} }
blocks.push(formatSymbolExport(symbol, namespaces, imports)); const line = formatSymbolExport(symbol, namespaces, imports);
if (line) {
blocks.push(line);
}
} }
}); });
const nsdefs = []; const nsdefs = [];