Skip to content

Commit

Permalink
Make export-order-loader compatible with both es and cjs
Browse files Browse the repository at this point in the history
  • Loading branch information
mlazari committed Jan 10, 2024
1 parent feb4a6a commit 492591a
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 20 deletions.
1 change: 1 addition & 0 deletions code/builders/builder-webpack5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
"@types/semver": "^7.3.4",
"browser-assert": "^1.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"cjs-module-lexer": "^1.2.3",
"constants-browserify": "^1.0.0",
"css-loader": "^6.7.1",
"es-module-lexer": "^1.4.1",
Expand Down
72 changes: 52 additions & 20 deletions code/builders/builder-webpack5/src/loaders/export-order-loader.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,66 @@
import { parse } from 'es-module-lexer';
import { parse as parseCjs, init as initCjsParser } from 'cjs-module-lexer';
import { parse as parseEs } from 'es-module-lexer';
import MagicString from 'magic-string';
import type { LoaderContext } from 'webpack';

export default async function loader(this: LoaderContext<any>, source: string) {
export default async function loader(
this: LoaderContext<any>,
source: string,
map: any,
meta: any
) {
const callback = this.async();

try {
// Do NOT remove await here. The types are wrong! It has to be awaited,
// otherwise it will return a Promise<Promise<...>> when wasm isn't loaded.
const [, exports = []] = await parse(source);

const namedExportsOrder = exports.some(
(e) => source.substring(e.s, e.e) === '__namedExportsOrder'
);
let isEsModule = true, esImports, moduleExports, namedExportsOrder;

try {
// Do NOT remove await here. The types are wrong! It has to be awaited,
// otherwise it will return a Promise<Promise<...>> when wasm isn't loaded.
const parseResult = await parseEs(source);
esImports = parseResult[0] || [];
moduleExports = parseResult[1] || [];
} catch {
esImports = [];
moduleExports = [];
}

if (!moduleExports.length && !esImports.length) {
isEsModule = false;
try {
await initCjsParser();
moduleExports = (parseCjs(source)).exports || [];
} catch {
moduleExports = [];
}
namedExportsOrder = moduleExports.filter(
(e) => e !== 'default' && e !== '__esModule'
);
} else {
namedExportsOrder = moduleExports.map(
(e) => source.substring(e.s, e.e)
).filter((e) => e !== 'default');
}

if (namedExportsOrder) {
return callback(null, source);
if (namedExportsOrder.indexOf('__namedExportsOrder') >= 0) {
return callback(null, source, map, meta);
}

const magicString = new MagicString(source);
const orderedExports = exports.filter((e) => source.substring(e.s, e.e) !== 'default');
magicString.append(
`;export const __namedExportsOrder = ${JSON.stringify(
orderedExports.map((e) => source.substring(e.s, e.e))
)};`
);
const namedExportsOrderString = JSON.stringify(namedExportsOrder);
if (isEsModule) {
magicString.append(
`;export const __namedExportsOrder = ${namedExportsOrderString};`
);
} else {
magicString.append(
`;module.exports.__namedExportsOrder = ${namedExportsOrderString};`
);
}

const map = magicString.generateMap({ hires: true });
return callback(null, magicString.toString(), map);
const generatedMap = magicString.generateMap({ hires: true });
return callback(null, magicString.toString(), generatedMap, meta);
} catch (err) {
return callback(err as any);
return callback(null, source, map, meta);
}
}
8 changes: 8 additions & 0 deletions code/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5228,6 +5228,7 @@ __metadata:
"@types/webpack-virtual-modules": "npm:^0.1.1"
browser-assert: "npm:^1.2.1"
case-sensitive-paths-webpack-plugin: "npm:^2.4.0"
cjs-module-lexer: "npm:^1.2.3"
constants-browserify: "npm:^1.0.0"
css-loader: "npm:^6.7.1"
es-module-lexer: "npm:^1.4.1"
Expand Down Expand Up @@ -11217,6 +11218,13 @@ __metadata:
languageName: node
linkType: hard

"cjs-module-lexer@npm:^1.2.3":
version: 1.2.3
resolution: "cjs-module-lexer@npm:1.2.3"
checksum: 0de9a9c3fad03a46804c0d38e7b712fb282584a9c7ef1ed44cae22fb71d9bb600309d66a9711ac36a596fd03422f5bb03e021e8f369c12a39fa1786ae531baab
languageName: node
linkType: hard

"class-utils@npm:^0.3.5":
version: 0.3.6
resolution: "class-utils@npm:0.3.6"
Expand Down

0 comments on commit 492591a

Please sign in to comment.