From 40f8e69675e626a053c17d1798099e341bf80b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20Kr=C3=B6g?= Date: Sun, 2 May 2021 23:18:19 +0200 Subject: [PATCH] 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. --- config/jsdoc/api/conf.json | 11 ++-- config/jsdoc/info/conf.json | 5 +- config/jsdoc/info/publish.js | 3 ++ config/jsdoc/{api => }/plugins/api.cjs | 34 ------------ config/jsdoc/plugins/default-export.cjs | 35 +++++++++++++ .../jsdoc/{info => plugins}/define-plugin.cjs | 0 config/jsdoc/{api => }/plugins/events.cjs | 0 .../{api => }/plugins/inline-options.cjs | 0 config/jsdoc/{api => }/plugins/markdown.cjs | 0 config/jsdoc/{api => }/plugins/observable.cjs | 0 .../{info => plugins}/virtual-plugin.cjs | 0 tasks/generate-index.js | 52 +++++++++++-------- 12 files changed, 77 insertions(+), 63 deletions(-) rename config/jsdoc/{api => }/plugins/api.cjs (83%) create mode 100644 config/jsdoc/plugins/default-export.cjs rename config/jsdoc/{info => plugins}/define-plugin.cjs (100%) rename config/jsdoc/{api => }/plugins/events.cjs (100%) rename config/jsdoc/{api => }/plugins/inline-options.cjs (100%) rename config/jsdoc/{api => }/plugins/markdown.cjs (100%) rename config/jsdoc/{api => }/plugins/observable.cjs (100%) rename config/jsdoc/{info => plugins}/virtual-plugin.cjs (100%) diff --git a/config/jsdoc/api/conf.json b/config/jsdoc/api/conf.json index 8fb5978971..a4a531ea2f 100644 --- a/config/jsdoc/api/conf.json +++ b/config/jsdoc/api/conf.json @@ -14,12 +14,13 @@ ] }, "plugins": [ - "config/jsdoc/api/plugins/markdown.cjs", + "config/jsdoc/plugins/markdown.cjs", "jsdoc-plugin-typescript", - "config/jsdoc/api/plugins/inline-options.cjs", - "config/jsdoc/api/plugins/events.cjs", - "config/jsdoc/api/plugins/observable.cjs", - "config/jsdoc/api/plugins/api.cjs" + "config/jsdoc/plugins/inline-options.cjs", + "config/jsdoc/plugins/events.cjs", + "config/jsdoc/plugins/observable.cjs", + "config/jsdoc/plugins/api.cjs", + "config/jsdoc/plugins/default-export.cjs" ], "typescript": { "moduleRoot": "src" diff --git a/config/jsdoc/info/conf.json b/config/jsdoc/info/conf.json index 2997676be2..4d0838bff1 100644 --- a/config/jsdoc/info/conf.json +++ b/config/jsdoc/info/conf.json @@ -11,8 +11,9 @@ }, "plugins": [ "jsdoc-plugin-typescript", - "config/jsdoc/info/define-plugin.cjs", - "config/jsdoc/info/virtual-plugin.cjs" + "config/jsdoc/plugins/define-plugin.cjs", + "config/jsdoc/plugins/virtual-plugin.cjs", + "config/jsdoc/plugins/default-export.cjs" ], "typescript": { "moduleRoot": "src" diff --git a/config/jsdoc/info/publish.js b/config/jsdoc/info/publish.js index 99b1b6b8d0..cdac68ea22 100644 --- a/config/jsdoc/info/publish.js +++ b/config/jsdoc/info/publish.js @@ -137,6 +137,9 @@ exports.publish = function (data, opts) { return true; }); } + if (doc.isDefaultExport) { + symbol.isDefaultExport = true; + } const target = isExterns ? externs : symbols; const existingSymbol = symbolsByName[symbol.name]; diff --git a/config/jsdoc/api/plugins/api.cjs b/config/jsdoc/plugins/api.cjs similarity index 83% rename from config/jsdoc/api/plugins/api.cjs rename to config/jsdoc/plugins/api.cjs index 5a91e76a27..cd65cafecf 100644 --- a/config/jsdoc/api/plugins/api.cjs +++ b/config/jsdoc/plugins/api.cjs @@ -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) { if (doclet.fires) { 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; - }); - } - }, }; diff --git a/config/jsdoc/plugins/default-export.cjs b/config/jsdoc/plugins/default-export.cjs new file mode 100644 index 0000000000..ccab779aef --- /dev/null +++ b/config/jsdoc/plugins/default-export.cjs @@ -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; + }); + } + }, +}; diff --git a/config/jsdoc/info/define-plugin.cjs b/config/jsdoc/plugins/define-plugin.cjs similarity index 100% rename from config/jsdoc/info/define-plugin.cjs rename to config/jsdoc/plugins/define-plugin.cjs diff --git a/config/jsdoc/api/plugins/events.cjs b/config/jsdoc/plugins/events.cjs similarity index 100% rename from config/jsdoc/api/plugins/events.cjs rename to config/jsdoc/plugins/events.cjs diff --git a/config/jsdoc/api/plugins/inline-options.cjs b/config/jsdoc/plugins/inline-options.cjs similarity index 100% rename from config/jsdoc/api/plugins/inline-options.cjs rename to config/jsdoc/plugins/inline-options.cjs diff --git a/config/jsdoc/api/plugins/markdown.cjs b/config/jsdoc/plugins/markdown.cjs similarity index 100% rename from config/jsdoc/api/plugins/markdown.cjs rename to config/jsdoc/plugins/markdown.cjs diff --git a/config/jsdoc/api/plugins/observable.cjs b/config/jsdoc/plugins/observable.cjs similarity index 100% rename from config/jsdoc/api/plugins/observable.cjs rename to config/jsdoc/plugins/observable.cjs diff --git a/config/jsdoc/info/virtual-plugin.cjs b/config/jsdoc/plugins/virtual-plugin.cjs similarity index 100% rename from config/jsdoc/info/virtual-plugin.cjs rename to config/jsdoc/plugins/virtual-plugin.cjs diff --git a/tasks/generate-index.js b/tasks/generate-index.js index c3e12f5acd..73d7fb3730 100644 --- a/tasks/generate-index.js +++ b/tasks/generate-index.js @@ -22,15 +22,20 @@ async function getSymbols() { */ function getImport(symbol, member) { const defaultExport = symbol.name.split('~'); - const namedExport = symbol.name.split('.'); - if (defaultExport.length > 1 && defaultExport[0].indexOf('.') === -1) { - const from = defaultExport[0].replace(/^module\:/, './') + '.js'; + if (symbol.isDefaultExport) { + const from = defaultExport[0].replace(/^module\:/, './'); const importName = from.replace(/[.\/]+/g, '$'); - return `import ${importName} from '${from}';`; - } else if (namedExport.length > 1 && member) { - const from = namedExport[0].replace(/^module\:/, './') + '.js'; + return `import ${importName} from '${from}.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, '_'); - return `import {${member} as ${importName}$${member}} from '${from}';`; + return `import {${member} as ${importName}$${member}} from '${from}.js';`; } } @@ -44,24 +49,24 @@ function getImport(symbol, member) { function formatSymbolExport(symbol, namespaces, imports) { const name = symbol.name; const parts = name.split('~'); - const isNamed = parts[0].indexOf('.') !== -1; const nsParts = parts[0].replace(/^module\:/, '').split(/[\/\.]/); const last = nsParts.length - 1; - const importName = isNamed - ? '_' + nsParts.slice(0, last).join('_') + '$' + nsParts[last] - : '$' + nsParts.join('$'); - let line = nsParts[0]; - for (let i = 1, ii = nsParts.length; i < ii; ++i) { - line += `.${nsParts[i]}`; - namespaces[line] = - (line in namespaces ? namespaces[line] : true) && i < ii - 1; - } - line += ` = ${importName} || {};`; - const imp = getImport(symbol, nsParts.pop()); + const imp = getImport(symbol, nsParts[last]); if (imp) { + const isNamed = parts[0].indexOf('.') !== -1; + const importName = isNamed + ? '_' + nsParts.slice(0, last).join('_') + '$' + nsParts[last] + : '$' + nsParts.join('$'); + let line = nsParts[0]; + for (let i = 1, ii = nsParts.length; i < ii; ++i) { + line += `.${nsParts[i]}`; + namespaces[line] = + (line in namespaces ? namespaces[line] : true) && i < ii - 1; + } + line += ` = ${importName};`; imports[imp] = true; + return line; } - return line; } /** @@ -71,7 +76,7 @@ function formatSymbolExport(symbol, namespaces, imports) { */ function generateExports(symbols) { const namespaces = {}; - const imports = []; + const imports = {}; const blocks = []; symbols.forEach(function (symbol) { const name = symbol.name; @@ -80,7 +85,10 @@ function generateExports(symbols) { if (imp) { imports[imp] = true; } - blocks.push(formatSymbolExport(symbol, namespaces, imports)); + const line = formatSymbolExport(symbol, namespaces, imports); + if (line) { + blocks.push(line); + } } }); const nsdefs = [];