Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS runtime improvements #6531

Merged
merged 8 commits into from
Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/core/core/src/public/Environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ const supportData = {
'service-worker-module': {
// TODO: Safari 14.1??
},
'import-meta-url': {
edge: '79',
firefox: '62',
chrome: '64',
safari: '11.1',
opera: '51',
ios: '12',
android: '64',
and_chr: '64',
and_ff: '62',
samsung: '9.2',
},
};

const internalEnvironmentToEnvironment: WeakMap<
Expand Down
9 changes: 0 additions & 9 deletions packages/core/integration-tests/test/javascript.js
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,6 @@ describe('javascript', function() {
'bundle-url.js',
'get-worker-url.js',
'bundle-manifest.js',
'relative-path.js',
'esmodule-helpers.js',
],
},
Expand All @@ -1472,7 +1471,6 @@ describe('javascript', function() {
'bundle-url.js',
'get-worker-url.js',
'bundle-manifest.js',
'relative-path.js',
],
},
{
Expand Down Expand Up @@ -1616,7 +1614,6 @@ describe('javascript', function() {
'bundle-url.js',
'get-worker-url.js',
'bundle-manifest.js',
'relative-path.js',
],
},
{
Expand Down Expand Up @@ -1757,7 +1754,6 @@ describe('javascript', function() {
'cacheLoader.js',
'js-loader.js',
'bundle-manifest.js',
'relative-path.js',
],
},
{
Expand Down Expand Up @@ -3607,7 +3603,6 @@ describe('javascript', function() {
'cacheLoader.js',
'dep.js',
'js-loader.js',
'relative-path.js',
'same-ancestry.js',
'esmodule-helpers.js',
],
Expand Down Expand Up @@ -3655,7 +3650,6 @@ describe('javascript', function() {
'cacheLoader.js',
'get-dep.js',
'js-loader.js',
'relative-path.js',
'esmodule-helpers.js',
],
},
Expand Down Expand Up @@ -3711,7 +3705,6 @@ describe('javascript', function() {
'cacheLoader.js',
'index.js',
'js-loader.js',
'relative-path.js',
'esmodule-helpers.js',
],
},
Expand Down Expand Up @@ -4136,7 +4129,6 @@ describe('javascript', function() {
'cacheLoader.js',
'js-loader.js',
'bundle-manifest.js',
'relative-path.js',
],
},
{
Expand Down Expand Up @@ -4214,7 +4206,6 @@ describe('javascript', function() {
'esmodule-helpers.js',
'js-loader.js',
'bundle-manifest.js',
'relative-path.js',
],
},
{
Expand Down
10 changes: 4 additions & 6 deletions packages/core/integration-tests/test/output-formats.js
Original file line number Diff line number Diff line change
Expand Up @@ -938,9 +938,9 @@ describe('output formats', function() {
);
assert(
new RegExp(
'Promise.all\\(\\[\\n.+?getBundleURL\\(\\) \\+ "' +
'Promise.all\\(\\[\\n.+?new URL\\("' +
path.basename(asyncCssBundle.filePath) +
'"\\),\\n\\s*import\\("\\.\\/' +
'", import.meta.url\\).toString\\(\\)\\),\\n\\s*import\\("\\.\\/' +
path.basename(asyncJsBundle.filePath) +
'"\\)\\n\\s*\\]\\)',
).test(entry),
Expand Down Expand Up @@ -993,9 +993,7 @@ describe('output formats', function() {
// async import both bundles in parallel for performance
assert(
new RegExp(
`import\\("\\./${path.basename(
sharedBundle.filePath,
)}"\\),\\n\\s*import\\("./${path.basename(bundle.filePath)}"\\)`,
`import\\("\\./" \\+ .+\.resolve\\("${sharedBundle.publicId}"\\)\\),\\n\\s*import\\("./" \\+ .+\.resolve\\("${bundle.publicId}"\\)\\)`,
).test(entry),
);
}
Expand Down Expand Up @@ -1216,7 +1214,7 @@ describe('output formats', function() {
assertBundles(b, [
{
type: 'js',
assets: ['bundle-url.js', 'get-worker-url.js', 'index.js'],
assets: ['bundle-manifest.js', 'get-worker-url.js', 'index.js'],
},
{type: 'html', assets: ['index.html']},
{type: 'js', assets: ['lodash.js']},
Expand Down
4 changes: 0 additions & 4 deletions packages/core/integration-tests/test/scope-hoisting.js
Original file line number Diff line number Diff line change
Expand Up @@ -5498,7 +5498,6 @@ describe('scope hoisting', function() {
'cacheLoader.js',
'dep.js',
'js-loader.js',
'relative-path.js',
'same-ancestry-scope-hoisting.js',
],
},
Expand All @@ -5525,7 +5524,6 @@ describe('scope hoisting', function() {
'bundle-url.js',
'cacheLoader.js',
'js-loader.js',
'relative-path.js',
],
},
{assets: ['dep.js']},
Expand Down Expand Up @@ -5566,7 +5564,6 @@ describe('scope hoisting', function() {
'cacheLoader.js',
'get-dep-scope-hoisting.js',
'js-loader.js',
'relative-path.js',
],
},
]);
Expand Down Expand Up @@ -5614,7 +5611,6 @@ describe('scope hoisting', function() {
'cacheLoader.js',
'scope-hoisting.js',
'js-loader.js',
'relative-path.js',
],
},
]);
Expand Down
3 changes: 3 additions & 0 deletions packages/core/test-utils/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,9 @@ export async function runESM(
identifier: filename + '?id=' + id,
importModuleDynamically: entry,
context,
initializeImportMeta(meta) {
meta.url = `http://localhost/${path.basename(filename)}`;
},
});
cache.set(filename, m);
return m;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ export type EnvironmentFeature =
| 'esmodules'
| 'dynamic-import'
| 'worker-module'
| 'service-worker-module';
| 'service-worker-module'
| 'import-meta-url';

/**
* Defines the environment in for the output bundle
Expand Down
90 changes: 64 additions & 26 deletions packages/runtimes/js/src/JSRuntime.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,11 @@ export default (new Runtime({
}),
);

if (bundle.env.outputFormat === 'commonjs' && mainBundle.type === 'js') {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This came from #4744 but I had to revert it because it breaks URL dependencies to a JS file in CJS output. I think the real solution to what the PR was trying to accomplish would be to make the dependency async.

if (
bundle.env.outputFormat === 'commonjs' &&
mainBundle.type === 'js' &&
dependency.specifierType !== 'url'
) {
assets.push({
filePath: __filename,
dependency,
Expand Down Expand Up @@ -224,7 +228,7 @@ export default (new Runtime({
);
let loaderCode = `require(${JSON.stringify(
loader,
)})(require('./bundle-url').getBundleURL() + ${relativePathExpr})`;
)})( ${getAbsoluteUrlExpr(relativePathExpr, bundle)})`;
assets.push({
filePath: __filename,
code: loaderCode,
Expand Down Expand Up @@ -332,7 +336,8 @@ function getLoaderRuntime({
}

// Determine if we need to add a dynamic import() polyfill, or if all target browsers support it natively.
let needsDynamicImportPolyfill = !bundle.env.supports('dynamic-import', true);
let needsDynamicImportPolyfill =
!bundle.env.isLibrary && !bundle.env.supports('dynamic-import', true);

let loaderModules = externalBundles
.map(to => {
Expand All @@ -357,9 +362,10 @@ function getLoaderRuntime({
return `Promise.resolve(__parcel__require__("./" + ${relativePathExpr}))`;
}

let code = `require(${JSON.stringify(
loader,
)})(require('./bundle-url').getBundleURL() + ${relativePathExpr})`;
let code = `require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(
relativePathExpr,
bundle,
)})`;

// In development, clear the require cache when an error occurs so the
// user can try again (e.g. after fixing a build error).
Expand Down Expand Up @@ -482,11 +488,10 @@ function getHintLoaders(
);
let priority = TYPE_TO_RESOURCE_PRIORITY[bundleToPreload.type];
hintLoaders.push(
`require(${JSON.stringify(
loader,
)})(require('./bundle-url').getBundleURL() + ${relativePathExpr}, ${
priority ? JSON.stringify(priority) : 'null'
}, ${JSON.stringify(
`require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(
relativePathExpr,
from,
)}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(
bundleToPreload.target.env.outputFormat === 'esmodule',
)})`,
);
Expand Down Expand Up @@ -521,20 +526,32 @@ function getURLRuntime(
options: PluginOptions,
): RuntimeAsset {
let relativePathExpr = getRelativePathExpr(from, to, options);
if (dependency.meta.webworker === true) {
return {
filePath: __filename,
code: `module.exports = require('./get-worker-url')(${relativePathExpr}, ${String(
let code;

if (dependency.meta.webworker === true && !from.env.isLibrary) {
code = `let workerURL = require('./get-worker-url');\n`;
if (
from.env.outputFormat === 'esmodule' &&
from.env.supports('import-meta-url')
) {
code += `let url = new __parcel__URL__(${relativePathExpr}, import.meta.url);\n`;
code += `module.exports = workerURL(url.toString(), url.origin, ${String(
from.env.outputFormat === 'esmodule',
)});`,
dependency,
env: {sourceType: 'module'},
};
)});`;
} else {
code += `let bundleURL = require('./bundle-url');\n`;
code += `let url = bundleURL.getBundleURL() + ${relativePathExpr};`;
code += `module.exports = workerURL(url, bundleURL.getOrigin(url), ${String(
from.env.outputFormat === 'esmodule',
)});`;
}
} else {
code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from)};`;
}

return {
filePath: __filename,
code: `module.exports = require('./bundle-url').getBundleURL() + ${relativePathExpr}`,
code,
dependency,
env: {sourceType: 'module'},
};
Expand All @@ -550,7 +567,7 @@ function getRegisterCode(
return;
}

idToName[bundle.publicId] = nullthrows(bundle.name);
idToName[bundle.publicId] = path.basename(nullthrows(bundle.name));

if (bundle !== entryBundle && isNewContext(bundle, bundleGraph)) {
// New contexts have their own manifests, so there's no need to continue.
Expand All @@ -570,13 +587,35 @@ function getRelativePathExpr(
to: NamedBundle,
options: PluginOptions,
): string {
let relativePath = relativeBundlePath(from, to, {leadingDotSlash: false});
if (shouldUseRuntimeManifest(from, options)) {
return `require('./relative-path')(${JSON.stringify(
from.publicId,
)}, ${JSON.stringify(to.publicId)})`;
// Get the relative part of the path. This part is not in the manifest, only the basename is.
let relativeBase = path.posix.dirname(relativePath);
if (relativeBase === '.') {
relativeBase = '';
} else {
relativeBase = `${JSON.stringify(relativeBase + '/')} + `;
}
return (
relativeBase +
`require('./bundle-manifest').resolve(${JSON.stringify(to.publicId)})`
);
}

return JSON.stringify(relativeBundlePath(from, to, {leadingDotSlash: false}));
return JSON.stringify(relativePath);
}

function getAbsoluteUrlExpr(relativePathExpr: string, bundle: Bundle) {
if (
bundle.env.outputFormat === 'esmodule' &&
(bundle.env.isLibrary || bundle.env.supports('import-meta-url'))
) {
return `new __parcel__URL__(${relativePathExpr}, import.meta.url).toString()`;
devongovett marked this conversation as resolved.
Show resolved Hide resolved
} else if (bundle.env.outputFormat === 'commonjs') {
return `require('path').join(__dirname, ${relativePathExpr})`;
devongovett marked this conversation as resolved.
Show resolved Hide resolved
} else {
return `require('./bundle-url').getBundleURL() + ${relativePathExpr}`;
}
}

function shouldUseRuntimeManifest(
Expand All @@ -587,7 +626,6 @@ function shouldUseRuntimeManifest(
return (
!env.isLibrary &&
bundle.bundleBehavior !== 'inline' &&
env.outputFormat === 'global' &&
env.isBrowser() &&
options.mode === 'production'
);
Expand Down
7 changes: 2 additions & 5 deletions packages/runtimes/js/src/get-worker-url.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
/* global self, Blob */

var bundleUrl = require('./bundle-url');

module.exports = function loadWorker(relativePath, isESM) {
var workerUrl = bundleUrl.getBundleURL() + relativePath;
if (bundleUrl.getOrigin(workerUrl) === self.location.origin) {
module.exports = function loadWorker(workerUrl, origin, isESM) {
if (origin === self.location.origin) {
// If the worker bundle's url is on the same origin as the document,
// use the worker bundle's own url.
return workerUrl;
Expand Down