Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .changeset/chilly-ravens-smile.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
"@lynx-js/externals-loading-webpack-plugin": patch
"@lynx-js/lynx-bundle-rslib-config": patch
---

Introduce `@lynx-js/externals-loading-webpack-plugin`.
Introduce `@lynx-js/externals-loading-webpack-plugin`. It will help you to load externals built by `@lynx-js/lynx-bundle-rslib-config`.

```js
// webpack.config.js
Expand Down
2 changes: 1 addition & 1 deletion examples/react-externals/lynx.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default defineConfig({
url: `${EXTERNAL_BUNDLE_PREFIX}/comp-lib.lynx.bundle`,
background: { sectionPath: 'CompLib' },
mainThread: { sectionPath: 'CompLib__main-thread' },
async: false,
async: true,
},
},
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,15 @@ function transformExternals(
): Required<LibOutputConfig>['externals'] {
if (!externals) return {}

return function({ request, contextInfo }, callback) {
return function({ request }, callback) {
if (!request) return callback()
const libraryName = externals[request]
if (!libraryName) return callback()

if (contextInfo?.issuerLayer === LAYERS.MAIN_THREAD) {
callback(undefined, [
'globalThis',
'lynx_ex',
...(Array.isArray(libraryName) ? libraryName : [libraryName]),
], 'var')
} else {
callback(undefined, [
'lynxCoreInject',
'tt',
'lynx_ex',
...(Array.isArray(libraryName) ? libraryName : [libraryName]),
], 'var')
}
callback(undefined, [
'lynx[Symbol.for("__LYNX_EXTERNAL_GLOBAL__")]',
...(Array.isArray(libraryName) ? libraryName : [libraryName]),
], 'var')
}
}

Expand Down
33 changes: 14 additions & 19 deletions packages/webpack/externals-loading-webpack-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export interface ExternalsLoadingPluginOptions {
*
* ```js
* externals: {
* lodash: '__webpack_require__.lynx_ex.lodash',
* lodash: 'lynx[Symbol.for("__LYNX_EXTERNAL_GLOBAL__")].lodash',
* }
* ```
*
Expand All @@ -129,8 +129,8 @@ export interface ExternalsLoadingPluginOptions {
*
* ```js
* externals: {
* lodash: '__webpack_require__.lynx_ex.Lodash',
* 'lodash-es': '__webpack_require__.lynx_ex.Lodash',
* lodash: 'lynx[Symbol.for("__LYNX_EXTERNAL_GLOBAL__")].Lodash',
* 'lodash-es': 'lynx[Symbol.for("__LYNX_EXTERNAL_GLOBAL__")].Lodash',
* }
* ```
*
Expand All @@ -151,7 +151,7 @@ export interface ExternalsLoadingPluginOptions {
*
* ```js
* externals: {
* preact: '__webpack_require__.lynx_ex.ReactLynx.Preact',
* preact: 'lynx[Symbol.for("__LYNX_EXTERNAL_GLOBAL__")].ReactLynx.Preact',
* }
* ```
*
Expand Down Expand Up @@ -204,11 +204,8 @@ export interface LayerOptions {
sectionPath: string;
}

function getLynxExternalGlobal(layer: 'background' | 'mainThread') {
// We do not use `globalThis` in BTS to avoid issues when sharing js context is enabled
return `${
layer === 'background' ? 'lynxCoreInject.tt.lynx_ex' : 'globalThis.lynx_ex'
}`;
function getLynxExternalGlobal() {
return `lynx[Symbol.for('__LYNX_EXTERNAL_GLOBAL__')]`;
}

/**
Expand Down Expand Up @@ -269,8 +266,7 @@ export class ExternalsLoadingPlugin {
chunkLayer: string,
): string {
const fetchCode: string[] = [];
const asyncLoadCode: string[] = [];
const syncLoadCode: string[] = [];
const loadCode: string[] = [];
// filter duplicate externals by libraryName or package name to avoid loading the same external multiple times. We keep the last one.
const externalsMap = new Map<
string | string[],
Expand Down Expand Up @@ -298,7 +294,7 @@ export class ExternalsLoadingPlugin {
if (externals.length === 0) {
return '';
}
const runtimeGlobalsInit = `${getLynxExternalGlobal(layer)} = {};`;
const runtimeGlobalsInit = `${getLynxExternalGlobal()} = {};`;
Comment thread
upupming marked this conversation as resolved.
const loadExternalFunc = `
function createLoadExternalAsync(handler, sectionPath) {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -365,8 +361,8 @@ function createLoadExternalSync(handler, sectionPath, timeout) {
);

if (async) {
asyncLoadCode.push(
`${getLynxExternalGlobal(layer)}[${
loadCode.push(
`${getLynxExternalGlobal()}[${
JSON.stringify(libraryNameStr)
}] = createLoadExternalAsync(handler${i}, ${
JSON.stringify(layerOptions.sectionPath)
Expand All @@ -375,8 +371,8 @@ function createLoadExternalSync(handler, sectionPath, timeout) {
continue;
}

syncLoadCode.push(
`${getLynxExternalGlobal(layer)}[${
loadCode.push(
`${getLynxExternalGlobal()}[${
JSON.stringify(libraryNameStr)
}] = createLoadExternalSync(handler${i}, ${
JSON.stringify(layerOptions.sectionPath)
Expand All @@ -388,8 +384,7 @@ function createLoadExternalSync(handler, sectionPath, timeout) {
runtimeGlobalsInit,
loadExternalFunc,
fetchCode,
asyncLoadCode,
syncLoadCode,
loadCode,
].flat().join('\n');
}
}
Expand Down Expand Up @@ -464,7 +459,7 @@ function createLoadExternalSync(handler, sectionPath, timeout) {
return callback(
undefined,
[
getLynxExternalGlobal(currentLayer),
getLynxExternalGlobal(),
...(Array.isArray(libraryName) ? libraryName : [libraryName]),
],
isAsync ? 'promise' : undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ it('should filter duplicate externals', async () => {
);
expect(
background.split(
'lynxCoreInject.tt.lynx_ex["Foo"] '
+ '= createLoadExternalSync(',
`lynx[Symbol.for('__LYNX_EXTERNAL_GLOBAL__')]["Foo"]`
+ ' = createLoadExternalSync(',
).length - 1,
).toBe(1);
expect(
mainThread.split(
'globalThis.lynx_ex["Foo"] '
`lynx[Symbol.for('__LYNX_EXTERNAL_GLOBAL__')]["Foo"] `
+ '= createLoadExternalSync(',
).length - 1,
).toBe(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ it('should external lodash and foo', async () => {
expect(background).toContain('module.exports ' + '= Lodash;');
expect(mainThread).toContain('module.exports ' + '= Lodash;');
expect(background).toContain(
'module.exports ' + '= lynxCoreInject.tt.lynx_ex.Foo;',
'module.exports ' + `= lynx[Symbol.for('__LYNX_EXTERNAL_GLOBAL__')].Foo;`,
);
expect(mainThread).toContain(
'module.exports ' + '= globalThis.lynx_ex.Foo;',
'module.exports ' + `= lynx[Symbol.for('__LYNX_EXTERNAL_GLOBAL__')].Foo;`,
);
});