larry babby and threejs for glsl

This commit is contained in:
Sam
2024-06-24 21:24:00 +12:00
parent 87d5dc634d
commit 907ebae4c0
6474 changed files with 1279596 additions and 8 deletions

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017-present Devon Govett
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CJSOutputFormat = void 0;
class CJSOutputFormat {
constructor(packager) {
this.packager = packager;
}
buildBundlePrelude() {
let res = '';
let lines = 0;
for (let [source, specifiers] of this.packager.externals) {
// CJS only supports the namespace symbol. This ensures that all accesses
// are live and the `this` binding is correct.
let namespace = specifiers.get('*');
if (namespace) {
res += `var ${namespace} = require(${JSON.stringify(source)});\n`;
lines++;
} else {
res += `require(${JSON.stringify(source)});\n`;
lines++;
}
}
if (res.length > 0) {
res += '\n';
lines++;
}
return [res, lines];
}
buildBundlePostlude() {
return ['', 0];
}
}
exports.CJSOutputFormat = CJSOutputFormat;

View File

@@ -0,0 +1,192 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DevPackager = void 0;
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
function _sourceMap() {
const data = _interopRequireDefault(require("@parcel/source-map"));
_sourceMap = function () {
return data;
};
return data;
}
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
var _utils2 = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const PRELUDE = _fs().default.readFileSync(_path().default.join(__dirname, 'dev-prelude.js'), 'utf8').trim().replace(/;$/, '');
class DevPackager {
constructor(options, bundleGraph, bundle, parcelRequireName) {
this.options = options;
this.bundleGraph = bundleGraph;
this.bundle = bundle;
this.parcelRequireName = parcelRequireName;
}
async package() {
// Load assets
let queue = new (_utils().PromiseQueue)({
maxConcurrent: 32
});
this.bundle.traverseAssets(asset => {
queue.add(async () => {
let [code, mapBuffer] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap && asset.getMapBuffer()]);
return {
code,
mapBuffer
};
});
});
let results = await queue.run();
let assets = '';
let i = 0;
let first = true;
let map = new (_sourceMap().default)(this.options.projectRoot);
let prefix = this.getPrefix();
let lineOffset = (0, _utils().countLines)(prefix);
let script = null;
this.bundle.traverse(node => {
let wrapped = first ? '' : ',';
if (node.type === 'dependency') {
let resolved = this.bundleGraph.getResolvedAsset(node.value, this.bundle);
if (resolved && resolved.type !== 'js') {
// if this is a reference to another javascript asset, we should not include
// its output, as its contents should already be loaded.
(0, _assert().default)(!this.bundle.hasAsset(resolved));
wrapped += JSON.stringify(this.bundleGraph.getAssetPublicId(resolved)) + ':[function() {},{}]';
} else {
return;
}
}
if (node.type === 'asset') {
let asset = node.value;
(0, _assert().default)(asset.type === 'js', 'all assets in a js bundle must be js assets');
// If this is the main entry of a script rather than a module, we need to hoist it
// outside the bundle wrapper function so that its variables are exposed as globals.
if (this.bundle.env.sourceType === 'script' && asset === this.bundle.getMainEntry()) {
script = results[i++];
return;
}
let deps = {};
let dependencies = this.bundleGraph.getDependencies(asset);
for (let dep of dependencies) {
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
if (this.bundleGraph.isDependencySkipped(dep)) {
deps[(0, _utils2.getSpecifier)(dep)] = false;
} else if (resolved) {
deps[(0, _utils2.getSpecifier)(dep)] = this.bundleGraph.getAssetPublicId(resolved);
} else {
// An external module - map placeholder to original specifier.
deps[(0, _utils2.getSpecifier)(dep)] = dep.specifier;
}
}
let {
code,
mapBuffer
} = results[i];
let output = code || '';
wrapped += JSON.stringify(this.bundleGraph.getAssetPublicId(asset)) + ':[function(require,module,exports) {\n' + output + '\n},';
wrapped += JSON.stringify(deps);
wrapped += ']';
if (this.bundle.env.isNode() && asset.meta.has_node_replacements === true) {
const relPath = (0, _utils().normalizeSeparators)(_path().default.relative(this.bundle.target.distDir, _path().default.dirname(asset.filePath)));
wrapped = wrapped.replace('$parcel$dirnameReplace', relPath);
wrapped = wrapped.replace('$parcel$filenameReplace', relPath);
}
if (this.bundle.env.sourceMap) {
if (mapBuffer) {
map.addBuffer(mapBuffer, lineOffset);
} else {
map.addEmptyMap(_path().default.relative(this.options.projectRoot, asset.filePath).replace(/\\+/g, '/'), output, lineOffset);
}
lineOffset += (0, _utils().countLines)(output) + 1;
}
i++;
}
assets += wrapped;
first = false;
});
let entries = this.bundle.getEntryAssets();
let mainEntry = this.bundle.getMainEntry();
if (!this.isEntry() && this.bundle.env.outputFormat === 'global' || this.bundle.env.sourceType === 'script') {
// In async bundles we don't want the main entry to execute until we require it
// as there might be dependencies in a sibling bundle that hasn't loaded yet.
entries = entries.filter(a => {
var _mainEntry;
return a.id !== ((_mainEntry = mainEntry) === null || _mainEntry === void 0 ? void 0 : _mainEntry.id);
});
mainEntry = null;
}
let contents = prefix + '({' + assets + '},' + JSON.stringify(entries.map(asset => this.bundleGraph.getAssetPublicId(asset))) + ', ' + JSON.stringify(mainEntry ? this.bundleGraph.getAssetPublicId(mainEntry) : null) + ', ' + JSON.stringify(this.parcelRequireName) + ')' + '\n';
// The entry asset of a script bundle gets hoisted outside the bundle wrapper function
// so that its variables become globals. We need to replace any require calls for
// runtimes with a parcelRequire call.
if (this.bundle.env.sourceType === 'script' && script) {
let entryMap;
let mapBuffer = script.mapBuffer;
if (mapBuffer) {
entryMap = new (_sourceMap().default)(this.options.projectRoot, mapBuffer);
}
contents += (0, _utils2.replaceScriptDependencies)(this.bundleGraph, this.bundle, script.code, entryMap, this.parcelRequireName);
if (this.bundle.env.sourceMap && entryMap) {
map.addSourceMap(entryMap, lineOffset);
}
}
return {
contents,
map
};
}
getPrefix() {
let interpreter;
let mainEntry = this.bundle.getMainEntry();
if (mainEntry && this.isEntry() && !this.bundle.target.env.isBrowser()) {
let _interpreter = mainEntry.meta.interpreter;
(0, _assert().default)(_interpreter == null || typeof _interpreter === 'string');
interpreter = _interpreter;
}
let importScripts = '';
if (this.bundle.env.isWorker()) {
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
for (let b of bundles) {
importScripts += `importScripts("${(0, _utils().relativeBundlePath)(this.bundle, b)}");\n`;
}
}
return (
// If the entry asset included a hashbang, repeat it at the top of the bundle
(interpreter != null ? `#!${interpreter}\n` : '') + importScripts + PRELUDE
);
}
isEntry() {
return !this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') || this.bundle.env.isIsolated() || this.bundle.bundleBehavior === 'isolated';
}
}
exports.DevPackager = DevPackager;

View File

@@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ESMOutputFormat = void 0;
class ESMOutputFormat {
constructor(packager) {
this.packager = packager;
}
buildBundlePrelude() {
let res = '';
let lines = 0;
for (let [source, specifiers] of this.packager.externals) {
let defaultSpecifier = null;
let namespaceSpecifier = null;
let namedSpecifiers = [];
for (let [imported, symbol] of specifiers) {
if (imported === 'default' /* || isCommonJS*/) {
defaultSpecifier = symbol;
} else if (imported === '*') {
namespaceSpecifier = `* as ${symbol}`;
} else {
let specifier = imported;
if (symbol !== imported) {
specifier += ` as ${symbol}`;
}
namedSpecifiers.push(specifier);
}
}
// ESModule syntax allows combining default and namespace specifiers, or default and named, but not all three.
let imported = '';
if (namespaceSpecifier) {
let s = namespaceSpecifier;
if (defaultSpecifier) {
s = `${defaultSpecifier}, ${namespaceSpecifier}`;
}
res += `import ${s} from ${JSON.stringify(source)};\n`;
lines++;
} else if (defaultSpecifier) {
imported = defaultSpecifier;
if (namedSpecifiers.length > 0) {
imported += `, {${namedSpecifiers.join(', ')}}`;
}
} else if (namedSpecifiers.length > 0) {
imported = `{${namedSpecifiers.join(', ')}}`;
}
if (imported.length > 0) {
res += `import ${imported} from ${JSON.stringify(source)};\n`;
lines++;
} else if (!namespaceSpecifier) {
res += `import ${JSON.stringify(source)};\n`;
lines++;
}
}
if (res.length > 0) {
res += '\n';
lines++;
}
return [res, lines];
}
buildBundlePostlude() {
let res = '';
let lines = 0;
let exportSpecifiers = [];
for (let {
asset,
exportSymbol,
local,
exportAs
} of this.packager.exportedSymbols.values()) {
if (this.packager.wrappedAssets.has(asset.id)) {
let obj = `parcelRequire("${this.packager.bundleGraph.getAssetPublicId(asset)}")`;
res += `\nvar ${local} = ${this.packager.getPropertyAccess(obj, exportSymbol)};`;
lines++;
}
for (let as of exportAs) {
let specifier = local;
if (exportAs !== local) {
specifier += ` as ${as}`;
}
exportSpecifiers.push(specifier);
}
}
if (exportSpecifiers.length > 0) {
res += `\nexport {${exportSpecifiers.join(', ')}};`;
lines++;
}
if (this.packager.needsPrelude && this.packager.shouldBundleQueue(this.packager.bundle)) {
// Should be last thing the bundle executes on intial eval
res += `\n$parcel$global.rlb(${JSON.stringify(this.packager.bundle.publicId)})`;
lines++;
}
return [res, lines];
}
}
exports.ESMOutputFormat = ESMOutputFormat;

View File

@@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.GlobalOutputFormat = void 0;
class GlobalOutputFormat {
constructor(packager) {
this.packager = packager;
}
buildBundlePrelude() {
let prelude = this.packager.bundle.env.supports('arrow-functions', true) ? '(() => {\n' : '(function () {\n';
return [prelude, 1];
}
buildBundlePostlude() {
return ['})();', 0];
}
}
exports.GlobalOutputFormat = GlobalOutputFormat;

View File

@@ -0,0 +1,990 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ScopeHoistingPackager = void 0;
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
function _sourceMap2() {
const data = _interopRequireDefault(require("@parcel/source-map"));
_sourceMap2 = function () {
return data;
};
return data;
}
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
function _assert() {
const data = _interopRequireDefault(require("assert"));
_assert = function () {
return data;
};
return data;
}
function _diagnostic() {
const data = _interopRequireWildcard(require("@parcel/diagnostic"));
_diagnostic = function () {
return data;
};
return data;
}
function _globals() {
const data = _interopRequireDefault(require("globals"));
_globals = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
var _ESMOutputFormat = require("./ESMOutputFormat");
var _CJSOutputFormat = require("./CJSOutputFormat");
var _GlobalOutputFormat = require("./GlobalOutputFormat");
var _helpers = require("./helpers");
var _utils2 = require("./utils");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
const IDENTIFIER_RE = /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u;
const ID_START_RE = /^[$_\p{ID_Start}]/u;
const NON_ID_CONTINUE_RE = /[^$_\u200C\u200D\p{ID_Continue}]/gu;
// General regex used to replace imports with the resolved code, references with resolutions,
// and count the number of newlines in the file for source maps.
const REPLACEMENT_RE = /\n|import\s+"([0-9a-f]{16}:.+?)";|(?:\$[0-9a-f]{16}\$exports)|(?:\$[0-9a-f]{16}\$(?:import|importAsync|require)\$[0-9a-f]+(?:\$[0-9a-f]+)?)/g;
const BUILTINS = Object.keys(_globals().default.builtin);
const GLOBALS_BY_CONTEXT = {
browser: new Set([...BUILTINS, ...Object.keys(_globals().default.browser)]),
'web-worker': new Set([...BUILTINS, ...Object.keys(_globals().default.worker)]),
'service-worker': new Set([...BUILTINS, ...Object.keys(_globals().default.serviceworker)]),
worklet: new Set([...BUILTINS]),
node: new Set([...BUILTINS, ...Object.keys(_globals().default.node)]),
'electron-main': new Set([...BUILTINS, ...Object.keys(_globals().default.node)]),
'electron-renderer': new Set([...BUILTINS, ...Object.keys(_globals().default.node), ...Object.keys(_globals().default.browser)])
};
const OUTPUT_FORMATS = {
esmodule: _ESMOutputFormat.ESMOutputFormat,
commonjs: _CJSOutputFormat.CJSOutputFormat,
global: _GlobalOutputFormat.GlobalOutputFormat
};
class ScopeHoistingPackager {
exportedSymbols = new Map();
externals = new Map();
topLevelNames = new Map();
seenAssets = new Set();
wrappedAssets = new Set();
hoistedRequires = new Map();
needsPrelude = false;
usedHelpers = new Set();
externalAssets = new Set();
constructor(options, bundleGraph, bundle, parcelRequireName, useAsyncBundleRuntime) {
this.options = options;
this.bundleGraph = bundleGraph;
this.bundle = bundle;
this.parcelRequireName = parcelRequireName;
this.useAsyncBundleRuntime = useAsyncBundleRuntime;
let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
this.outputFormat = new OutputFormat(this);
this.isAsyncBundle = this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') && !this.bundle.env.isIsolated() && this.bundle.bundleBehavior !== 'isolated';
this.globalNames = GLOBALS_BY_CONTEXT[bundle.env.context];
}
async package() {
var _sourceMap;
let wrappedAssets = await this.loadAssets();
this.buildExportedSymbols();
// If building a library, the target is actually another bundler rather
// than the final output that could be loaded in a browser. So, loader
// runtimes are excluded, and instead we add imports into the entry bundle
// of each bundle group pointing at the sibling bundles. These can be
// picked up by another bundler later at which point runtimes will be added.
if (this.bundle.env.isLibrary || this.bundle.env.outputFormat === 'commonjs') {
for (let b of this.bundleGraph.getReferencedBundles(this.bundle)) {
let entry = b.getMainEntry();
let symbols = new Map();
if (entry && !this.isAsyncBundle && entry.type === 'js') {
this.externalAssets.add(entry);
let usedSymbols = this.bundleGraph.getUsedSymbols(entry) || new Set();
for (let s of usedSymbols) {
// If the referenced bundle is ESM, and we are importing '*', use 'default' instead.
// This matches the logic below in buildExportedSymbols.
let imported = s;
if (imported === '*' && b.env.outputFormat === 'esmodule') {
imported = 'default';
}
symbols.set(imported, this.getSymbolResolution(entry, entry, s));
}
}
this.externals.set((0, _utils().relativeBundlePath)(this.bundle, b), symbols);
}
}
let res = '';
let lineCount = 0;
let sourceMap = null;
let processAsset = asset => {
let [content, map, lines] = this.visitAsset(asset);
if (sourceMap && map) {
sourceMap.addSourceMap(map, lineCount);
} else if (this.bundle.env.sourceMap) {
sourceMap = map;
}
res += content + '\n';
lineCount += lines + 1;
};
// Hoist wrapped asset to the top of the bundle to ensure that they are registered
// before they are used.
for (let asset of wrappedAssets) {
if (!this.seenAssets.has(asset.id)) {
processAsset(asset);
}
}
// Add each asset that is directly connected to the bundle. Dependencies will be handled
// by replacing `import` statements in the code.
this.bundle.traverseAssets((asset, _, actions) => {
if (this.seenAssets.has(asset.id)) {
actions.skipChildren();
return;
}
processAsset(asset);
actions.skipChildren();
});
let [prelude, preludeLines] = this.buildBundlePrelude();
res = prelude + res;
lineCount += preludeLines;
(_sourceMap = sourceMap) === null || _sourceMap === void 0 || _sourceMap.offsetLines(1, preludeLines);
let entries = this.bundle.getEntryAssets();
let mainEntry = this.bundle.getMainEntry();
if (this.isAsyncBundle) {
// In async bundles we don't want the main entry to execute until we require it
// as there might be dependencies in a sibling bundle that hasn't loaded yet.
entries = entries.filter(a => {
var _mainEntry;
return a.id !== ((_mainEntry = mainEntry) === null || _mainEntry === void 0 ? void 0 : _mainEntry.id);
});
mainEntry = null;
}
let needsBundleQueue = this.shouldBundleQueue(this.bundle);
// If any of the entry assets are wrapped, call parcelRequire so they are executed.
for (let entry of entries) {
if (this.wrappedAssets.has(entry.id) && !this.isScriptEntry(entry)) {
var _entry$symbols$get;
let parcelRequire = `parcelRequire(${JSON.stringify(this.bundleGraph.getAssetPublicId(entry))});\n`;
let entryExports = (_entry$symbols$get = entry.symbols.get('*')) === null || _entry$symbols$get === void 0 ? void 0 : _entry$symbols$get.local;
if (entryExports && entry === mainEntry && this.exportedSymbols.has(entryExports)) {
(0, _assert().default)(!needsBundleQueue, 'Entry exports are not yet compaitble with async bundles');
res += `\nvar ${entryExports} = ${parcelRequire}`;
} else {
if (needsBundleQueue) {
parcelRequire = this.runWhenReady(this.bundle, parcelRequire);
}
res += `\n${parcelRequire}`;
}
lineCount += 2;
}
}
let [postlude, postludeLines] = this.outputFormat.buildBundlePostlude();
res += postlude;
lineCount += postludeLines;
// The entry asset of a script bundle gets hoisted outside the bundle wrapper so that
// its top-level variables become globals like a real browser script. We need to replace
// all dependency references for runtimes with a parcelRequire call.
if (this.bundle.env.outputFormat === 'global' && this.bundle.env.sourceType === 'script') {
res += '\n';
lineCount++;
let mainEntry = (0, _nullthrows().default)(this.bundle.getMainEntry());
let {
code,
map: mapBuffer
} = (0, _nullthrows().default)(this.assetOutputs.get(mainEntry.id));
let map;
if (mapBuffer) {
map = new (_sourceMap2().default)(this.options.projectRoot, mapBuffer);
}
res += (0, _utils2.replaceScriptDependencies)(this.bundleGraph, this.bundle, code, map, this.parcelRequireName);
if (sourceMap && map) {
sourceMap.addSourceMap(map, lineCount);
}
}
return {
contents: res,
map: sourceMap
};
}
shouldBundleQueue(bundle) {
return this.useAsyncBundleRuntime && bundle.type === 'js' && bundle.bundleBehavior !== 'inline' && bundle.env.outputFormat === 'esmodule' && !bundle.env.isIsolated() && bundle.bundleBehavior !== 'isolated' && !this.bundleGraph.hasParentBundleOfType(bundle, 'js');
}
runWhenReady(bundle, codeToRun) {
let deps = this.bundleGraph.getReferencedBundles(bundle).filter(b => this.shouldBundleQueue(b)).map(b => b.publicId);
if (deps.length === 0) {
// If no deps we can safely execute immediately
return codeToRun;
}
let params = [JSON.stringify(this.bundle.publicId), (0, _helpers.fnExpr)(this.bundle.env, [], [codeToRun]), JSON.stringify(deps)];
return `$parcel$global.rwr(${params.join(', ')});`;
}
async loadAssets() {
let queue = new (_utils().PromiseQueue)({
maxConcurrent: 32
});
let wrapped = [];
this.bundle.traverseAssets(asset => {
queue.add(async () => {
let [code, map] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap ? asset.getMapBuffer() : null]);
return [asset.id, {
code,
map
}];
});
if (asset.meta.shouldWrap || this.isAsyncBundle || this.bundle.env.sourceType === 'script' || this.bundleGraph.isAssetReferenced(this.bundle, asset) || this.bundleGraph.getIncomingDependencies(asset).some(dep => dep.meta.shouldWrap && dep.specifierType !== 'url')) {
if (!asset.meta.isConstantModule) {
this.wrappedAssets.add(asset.id);
wrapped.push(asset);
}
}
});
for (let wrappedAssetRoot of [...wrapped]) {
this.bundle.traverseAssets((asset, _, actions) => {
if (asset === wrappedAssetRoot) {
return;
}
if (this.wrappedAssets.has(asset.id)) {
actions.skipChildren();
return;
}
if (!asset.meta.isConstantModule) {
this.wrappedAssets.add(asset.id);
wrapped.push(asset);
}
}, wrappedAssetRoot);
}
this.assetOutputs = new Map(await queue.run());
return wrapped;
}
buildExportedSymbols() {
if (this.isAsyncBundle || !this.bundle.env.isLibrary || this.bundle.env.outputFormat !== 'esmodule') {
return;
}
// TODO: handle ESM exports of wrapped entry assets...
let entry = this.bundle.getMainEntry();
if (entry && !this.wrappedAssets.has(entry.id)) {
for (let {
asset,
exportAs,
symbol,
exportSymbol
} of this.bundleGraph.getExportedSymbols(entry)) {
if (typeof symbol === 'string') {
var _this$exportedSymbols, _entry$symbols$get2;
let symbols = (_this$exportedSymbols = this.exportedSymbols.get(symbol === '*' ? (0, _nullthrows().default)((_entry$symbols$get2 = entry.symbols.get('*')) === null || _entry$symbols$get2 === void 0 ? void 0 : _entry$symbols$get2.local) : symbol)) === null || _this$exportedSymbols === void 0 ? void 0 : _this$exportedSymbols.exportAs;
if (!symbols) {
symbols = [];
this.exportedSymbols.set(symbol, {
asset,
exportSymbol,
local: symbol,
exportAs: symbols
});
}
if (exportAs === '*') {
exportAs = 'default';
}
symbols.push(exportAs);
} else if (symbol === null) {
// TODO `meta.exportsIdentifier[exportSymbol]` should be exported
// let relativePath = relative(options.projectRoot, asset.filePath);
// throw getThrowableDiagnosticForNode(
// md`${relativePath} couldn't be statically analyzed when importing '${exportSymbol}'`,
// entry.filePath,
// loc,
// );
} else if (symbol !== false) {
// let relativePath = relative(options.projectRoot, asset.filePath);
// throw getThrowableDiagnosticForNode(
// md`${relativePath} does not export '${exportSymbol}'`,
// entry.filePath,
// loc,
// );
}
}
}
}
getTopLevelName(name) {
name = name.replace(NON_ID_CONTINUE_RE, '');
if (!ID_START_RE.test(name) || this.globalNames.has(name)) {
name = '_' + name;
}
let count = this.topLevelNames.get(name);
if (count == null) {
this.topLevelNames.set(name, 1);
return name;
}
this.topLevelNames.set(name, count + 1);
return name + count;
}
getPropertyAccess(obj, property) {
if (IDENTIFIER_RE.test(property)) {
return `${obj}.${property}`;
}
return `${obj}[${JSON.stringify(property)}]`;
}
visitAsset(asset) {
(0, _assert().default)(!this.seenAssets.has(asset.id), 'Already visited asset');
this.seenAssets.add(asset.id);
let {
code,
map
} = (0, _nullthrows().default)(this.assetOutputs.get(asset.id));
return this.buildAsset(asset, code, map);
}
buildAsset(asset, code, map) {
let shouldWrap = this.wrappedAssets.has(asset.id);
let deps = this.bundleGraph.getDependencies(asset);
let sourceMap = this.bundle.env.sourceMap && map ? new (_sourceMap2().default)(this.options.projectRoot, map) : null;
// If this asset is skipped, just add dependencies and not the asset's content.
if (this.shouldSkipAsset(asset)) {
let depCode = '';
let lineCount = 0;
for (let dep of deps) {
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
let skipped = this.bundleGraph.isDependencySkipped(dep);
if (skipped) {
continue;
}
if (!resolved) {
if (!dep.isOptional) {
this.addExternal(dep);
}
continue;
}
if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
let [code, map, lines] = this.visitAsset(resolved);
depCode += code + '\n';
if (sourceMap && map) {
sourceMap.addSourceMap(map, lineCount);
}
lineCount += lines + 1;
}
}
return [depCode, sourceMap, lineCount];
}
// TODO: maybe a meta prop?
if (code.includes('$parcel$global')) {
this.usedHelpers.add('$parcel$global');
}
if (this.bundle.env.isNode() && asset.meta.has_node_replacements) {
const relPath = (0, _utils().normalizeSeparators)(_path().default.relative(this.bundle.target.distDir, _path().default.dirname(asset.filePath)));
code = code.replace('$parcel$dirnameReplace', relPath);
code = code.replace('$parcel$filenameReplace', relPath);
}
let [depMap, replacements] = this.buildReplacements(asset, deps);
let [prepend, prependLines, append] = this.buildAssetPrelude(asset, deps);
if (prependLines > 0) {
sourceMap === null || sourceMap === void 0 || sourceMap.offsetLines(1, prependLines);
code = prepend + code;
}
code += append;
let lineCount = 0;
let depContent = [];
if (depMap.size === 0 && replacements.size === 0) {
// If there are no dependencies or replacements, use a simple function to count the number of lines.
lineCount = (0, _utils().countLines)(code) - 1;
} else {
// Otherwise, use a regular expression to perform replacements.
// We need to track how many newlines there are for source maps, replace
// all import statements with dependency code, and perform inline replacements
// of all imported symbols with their resolved export symbols. This is all done
// in a single regex so that we only do one pass over the whole code.
let offset = 0;
let columnStartIndex = 0;
code = code.replace(REPLACEMENT_RE, (m, d, i) => {
var _replacements$get;
if (m === '\n') {
columnStartIndex = i + offset + 1;
lineCount++;
return '\n';
}
// If we matched an import, replace with the source code for the dependency.
if (d != null) {
let deps = depMap.get(d);
if (!deps) {
return m;
}
let replacement = '';
// A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
// reexports.
for (let dep of deps) {
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
let skipped = this.bundleGraph.isDependencySkipped(dep);
if (resolved && !skipped) {
// Hoist variable declarations for the referenced parcelRequire dependencies
// after the dependency is declared. This handles the case where the resulting asset
// is wrapped, but the dependency in this asset is not marked as wrapped. This means
// that it was imported/required at the top-level, so its side effects should run immediately.
let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
let map;
if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
// If this asset is wrapped, we need to hoist the code for the dependency
// outside our parcelRequire.register wrapper. This is safe because all
// assets referenced by this asset will also be wrapped. Otherwise, inline the
// asset content where the import statement was.
if (shouldWrap) {
depContent.push(this.visitAsset(resolved));
} else {
let [depCode, depMap, depLines] = this.visitAsset(resolved);
res = depCode + '\n' + res;
lines += 1 + depLines;
map = depMap;
}
}
// Push this asset's source mappings down by the number of lines in the dependency
// plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
if (sourceMap) {
if (lines > 0) {
sourceMap.offsetLines(lineCount + 1, lines);
}
if (map) {
sourceMap.addSourceMap(map, lineCount);
}
}
replacement += res;
lineCount += lines;
}
}
return replacement;
}
// If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
let replacement = (_replacements$get = replacements.get(m)) !== null && _replacements$get !== void 0 ? _replacements$get : m;
if (sourceMap) {
// Offset the source map columns for this line if the replacement was a different length.
// This assumes that the match and replacement both do not contain any newlines.
let lengthDifference = replacement.length - m.length;
if (lengthDifference !== 0) {
sourceMap.offsetColumns(lineCount + 1, i + offset - columnStartIndex + m.length, lengthDifference);
offset += lengthDifference;
}
}
return replacement;
});
}
// If the asset is wrapped, we need to insert the dependency code outside the parcelRequire.register
// wrapper. Dependencies must be inserted AFTER the asset is registered so that circular dependencies work.
if (shouldWrap) {
// Offset by one line for the parcelRequire.register wrapper.
sourceMap === null || sourceMap === void 0 || sourceMap.offsetLines(1, 1);
lineCount++;
code = `parcelRegister(${JSON.stringify(this.bundleGraph.getAssetPublicId(asset))}, function(module, exports) {
${code}
});
`;
lineCount += 2;
for (let [depCode, map, lines] of depContent) {
if (!depCode) continue;
code += depCode + '\n';
if (sourceMap && map) {
sourceMap.addSourceMap(map, lineCount);
}
lineCount += lines + 1;
}
this.needsPrelude = true;
}
if (!shouldWrap && this.shouldBundleQueue(this.bundle) && this.bundle.getEntryAssets().some(entry => entry.id === asset.id)) {
code = this.runWhenReady(this.bundle, code);
}
return [code, sourceMap, lineCount];
}
buildReplacements(asset, deps) {
let assetId = asset.meta.id;
(0, _assert().default)(typeof assetId === 'string');
// Build two maps: one of import specifiers, and one of imported symbols to replace.
// These will be used to build a regex below.
let depMap = new (_utils().DefaultMap)(() => []);
let replacements = new Map();
for (let dep of deps) {
let specifierType = dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
depMap.get(`${assetId}:${(0, _utils2.getSpecifier)(dep)}${!dep.meta.placeholder ? specifierType : ''}`).push(dep);
let asyncResolution = this.bundleGraph.resolveAsyncDependency(dep, this.bundle);
let resolved = (asyncResolution === null || asyncResolution === void 0 ? void 0 : asyncResolution.type) === 'asset' ?
// Prefer the underlying asset over a runtime to load it. It will
// be wrapped in Promise.resolve() later.
asyncResolution.value : this.bundleGraph.getResolvedAsset(dep, this.bundle);
if (!resolved && !dep.isOptional && !this.bundleGraph.isDependencySkipped(dep)) {
this.addExternal(dep, replacements);
}
if (!resolved) {
continue;
}
for (let [imported, {
local
}] of dep.symbols) {
if (local === '*') {
continue;
}
let symbol = this.getSymbolResolution(asset, resolved, imported, dep);
replacements.set(local,
// If this was an internalized async asset, wrap in a Promise.resolve.
(asyncResolution === null || asyncResolution === void 0 ? void 0 : asyncResolution.type) === 'asset' ? `Promise.resolve(${symbol})` : symbol);
}
// Async dependencies need a namespace object even if all used symbols were statically analyzed.
// This is recorded in the promiseSymbol meta property set by the transformer rather than in
// symbols so that we don't mark all symbols as used.
if (dep.priority === 'lazy' && dep.meta.promiseSymbol) {
let promiseSymbol = dep.meta.promiseSymbol;
(0, _assert().default)(typeof promiseSymbol === 'string');
let symbol = this.getSymbolResolution(asset, resolved, '*', dep);
replacements.set(promiseSymbol, (asyncResolution === null || asyncResolution === void 0 ? void 0 : asyncResolution.type) === 'asset' ? `Promise.resolve(${symbol})` : symbol);
}
}
// If this asset is wrapped, we need to replace the exports namespace with `module.exports`,
// which will be provided to us by the wrapper.
if (this.wrappedAssets.has(asset.id) || this.bundle.env.outputFormat === 'commonjs' && asset === this.bundle.getMainEntry()) {
var _asset$symbols$get;
let exportsName = ((_asset$symbols$get = asset.symbols.get('*')) === null || _asset$symbols$get === void 0 ? void 0 : _asset$symbols$get.local) || `$${assetId}$exports`;
replacements.set(exportsName, 'module.exports');
}
return [depMap, replacements];
}
addExternal(dep, replacements) {
if (this.bundle.env.outputFormat === 'global') {
throw new (_diagnostic().default)({
diagnostic: {
message: 'External modules are not supported when building for browser',
codeFrames: [{
filePath: (0, _nullthrows().default)(dep.sourcePath),
codeHighlights: dep.loc ? [(0, _diagnostic().convertSourceLocationToHighlight)(dep.loc)] : []
}]
}
});
}
// Map of DependencySpecifier -> Map<ExportedSymbol, Identifier>>
let external = this.externals.get(dep.specifier);
if (!external) {
external = new Map();
this.externals.set(dep.specifier, external);
}
for (let [imported, {
local
}] of dep.symbols) {
// If already imported, just add the already renamed variable to the mapping.
let renamed = external.get(imported);
if (renamed && local !== '*' && replacements) {
replacements.set(local, renamed);
continue;
}
// For CJS output, always use a property lookup so that exports remain live.
// For ESM output, use named imports which are always live.
if (this.bundle.env.outputFormat === 'commonjs') {
renamed = external.get('*');
if (!renamed) {
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
external.set('*', renamed);
}
if (local !== '*' && replacements) {
let replacement;
if (imported === '*') {
replacement = renamed;
} else if (imported === 'default') {
replacement = `($parcel$interopDefault(${renamed}))`;
this.usedHelpers.add('$parcel$interopDefault');
} else {
replacement = this.getPropertyAccess(renamed, imported);
}
replacements.set(local, replacement);
}
} else {
// Rename the specifier so that multiple local imports of the same imported specifier
// are deduplicated. We have to prefix the imported name with the bundle id so that
// local variables do not shadow it.
if (this.exportedSymbols.has(local)) {
renamed = local;
} else if (imported === 'default' || imported === '*') {
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${dep.specifier}`);
} else {
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${imported}`);
}
external.set(imported, renamed);
if (local !== '*' && replacements) {
replacements.set(local, renamed);
}
}
}
}
isWrapped(resolved, parentAsset) {
if (resolved.meta.isConstantModule) {
(0, _assert().default)(this.bundle.hasAsset(resolved), 'Constant module not found in bundle');
return false;
}
return !this.bundle.hasAsset(resolved) && !this.externalAssets.has(resolved) || this.wrappedAssets.has(resolved.id) && resolved !== parentAsset;
}
getSymbolResolution(parentAsset, resolved, imported, dep) {
var _resolvedAsset$symbol;
let {
asset: resolvedAsset,
exportSymbol,
symbol
} = this.bundleGraph.getSymbolResolution(resolved, imported, this.bundle);
if (resolvedAsset.type !== 'js' || dep && this.bundleGraph.isDependencySkipped(dep)) {
// Graceful fallback for non-js imports or when trying to resolve a symbol
// that is actually unused but we still need a placeholder value.
return '{}';
}
let isWrapped = this.isWrapped(resolvedAsset, parentAsset);
let staticExports = resolvedAsset.meta.staticExports !== false;
let publicId = this.bundleGraph.getAssetPublicId(resolvedAsset);
// External CommonJS dependencies need to be accessed as an object property rather than imported
// directly to maintain live binding.
let isExternalCommonJS = !isWrapped && this.bundle.env.isLibrary && this.bundle.env.outputFormat === 'commonjs' && !this.bundle.hasAsset(resolvedAsset);
// If the resolved asset is wrapped, but imported at the top-level by this asset,
// then we hoist parcelRequire calls to the top of this asset so side effects run immediately.
if (isWrapped && dep && !(dep !== null && dep !== void 0 && dep.meta.shouldWrap) && symbol !== false && (
// Only do this if the asset is part of a different bundle (so it was definitely
// parcelRequire.register'ed there), or if it is indeed registered in this bundle.
!this.bundle.hasAsset(resolvedAsset) || !this.shouldSkipAsset(resolvedAsset))) {
let hoisted = this.hoistedRequires.get(dep.id);
if (!hoisted) {
hoisted = new Map();
this.hoistedRequires.set(dep.id, hoisted);
}
hoisted.set(resolvedAsset.id, `var $${publicId} = parcelRequire(${JSON.stringify(publicId)});`);
}
if (isWrapped) {
this.needsPrelude = true;
}
// If this is an ESM default import of a CJS module with a `default` symbol,
// and no __esModule flag, we need to resolve to the namespace instead.
let isDefaultInterop = exportSymbol === 'default' && staticExports && !isWrapped && ((dep === null || dep === void 0 ? void 0 : dep.meta.kind) === 'Import' || (dep === null || dep === void 0 ? void 0 : dep.meta.kind) === 'Export') && resolvedAsset.symbols.hasExportSymbol('*') && resolvedAsset.symbols.hasExportSymbol('default') && !resolvedAsset.symbols.hasExportSymbol('__esModule');
// Find the namespace object for the resolved module. If wrapped and this
// is an inline require (not top-level), use a parcelRequire call, otherwise
// the hoisted variable declared above. Otherwise, if not wrapped, use the
// namespace export symbol.
let assetId = resolvedAsset.meta.id;
(0, _assert().default)(typeof assetId === 'string');
let obj = isWrapped && (!dep || dep !== null && dep !== void 0 && dep.meta.shouldWrap) ?
// Wrap in extra parenthesis to not change semantics, e.g.`new (parcelRequire("..."))()`.
`(parcelRequire(${JSON.stringify(publicId)}))` : isWrapped && dep ? `$${publicId}` : ((_resolvedAsset$symbol = resolvedAsset.symbols.get('*')) === null || _resolvedAsset$symbol === void 0 ? void 0 : _resolvedAsset$symbol.local) || `$${assetId}$exports`;
if (imported === '*' || exportSymbol === '*' || isDefaultInterop) {
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
if (parentAsset === resolvedAsset && this.wrappedAssets.has(resolvedAsset.id)) {
// Directly use module.exports for wrapped assets importing themselves.
return 'module.exports';
} else {
return obj;
}
} else if ((!staticExports || isWrapped || !symbol || isExternalCommonJS) && resolvedAsset !== parentAsset) {
// If the resolved asset is wrapped or has non-static exports,
// we need to use a member access off the namespace object rather
// than a direct reference. If importing default from a CJS module,
// use a helper to check the __esModule flag at runtime.
let kind = dep === null || dep === void 0 ? void 0 : dep.meta.kind;
if ((!dep || kind === 'Import' || kind === 'Export') && exportSymbol === 'default' && resolvedAsset.symbols.hasExportSymbol('*') && this.needsDefaultInterop(resolvedAsset)) {
this.usedHelpers.add('$parcel$interopDefault');
return `(/*@__PURE__*/$parcel$interopDefault(${obj}))`;
} else {
return this.getPropertyAccess(obj, exportSymbol);
}
} else if (!symbol) {
(0, _assert().default)(false, 'Asset was skipped or not found.');
} else {
return symbol;
}
}
getHoistedParcelRequires(parentAsset, dep, resolved) {
if (resolved.type !== 'js') {
return ['', 0];
}
let hoisted = this.hoistedRequires.get(dep.id);
let res = '';
let lineCount = 0;
let isWrapped = this.isWrapped(resolved, parentAsset);
// If the resolved asset is wrapped and is imported in the top-level by this asset,
// we need to run side effects when this asset runs. If the resolved asset is not
// the first one in the hoisted requires, we need to insert a parcelRequire here
// so it runs first.
if (isWrapped && !dep.meta.shouldWrap && (!hoisted || hoisted.keys().next().value !== resolved.id) && !this.bundleGraph.isDependencySkipped(dep) && !this.shouldSkipAsset(resolved)) {
this.needsPrelude = true;
res += `parcelRequire(${JSON.stringify(this.bundleGraph.getAssetPublicId(resolved))});`;
}
if (hoisted) {
this.needsPrelude = true;
res += '\n' + [...hoisted.values()].join('\n');
lineCount += hoisted.size;
}
return [res, lineCount];
}
buildAssetPrelude(asset, deps) {
let prepend = '';
let prependLineCount = 0;
let append = '';
let shouldWrap = this.wrappedAssets.has(asset.id);
let usedSymbols = (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(asset));
let assetId = asset.meta.id;
(0, _assert().default)(typeof assetId === 'string');
// If the asset has a namespace export symbol, it is CommonJS.
// If there's no __esModule flag, and default is a used symbol, we need
// to insert an interop helper.
let defaultInterop = asset.symbols.hasExportSymbol('*') && usedSymbols.has('default') && !asset.symbols.hasExportSymbol('__esModule');
let usedNamespace =
// If the asset has * in its used symbols, we might need the exports namespace.
// The one case where this isn't true is in ESM library entries, where the only
// dependency on * is the entry dependency. In this case, we will use ESM exports
// instead of the namespace object.
usedSymbols.has('*') && (this.bundle.env.outputFormat !== 'esmodule' || !this.bundle.env.isLibrary || asset !== this.bundle.getMainEntry() || this.bundleGraph.getIncomingDependencies(asset).some(dep => !dep.isEntry && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'))) ||
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
// we fallback on the namespace object.
asset.symbols.hasExportSymbol('*') && [...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s)) ||
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
// include the namespace object for the default export.
this.exportedSymbols.has(`$${assetId}$exports`);
// If the asset doesn't have static exports, should wrap, the namespace is used,
// or we need default interop, then we need to synthesize a namespace object for
// this asset.
if (asset.meta.staticExports === false || shouldWrap || usedNamespace || defaultInterop) {
// Insert a declaration for the exports namespace object. If the asset is wrapped
// we don't need to do this, because we'll use the `module.exports` object provided
// by the wrapper instead. This is also true of CommonJS entry assets, which will use
// the `module.exports` object provided by CJS.
if (!shouldWrap && (this.bundle.env.outputFormat !== 'commonjs' || asset !== this.bundle.getMainEntry())) {
prepend += `var $${assetId}$exports = {};\n`;
prependLineCount++;
}
// Insert the __esModule interop flag for this module if it has a `default` export
// and the namespace symbol is used.
// TODO: only if required by CJS?
if (asset.symbols.hasExportSymbol('default') && usedSymbols.has('*')) {
prepend += `\n$parcel$defineInteropFlag($${assetId}$exports);\n`;
prependLineCount += 2;
this.usedHelpers.add('$parcel$defineInteropFlag');
}
// Find wildcard re-export dependencies, and make sure their exports are also included in
// ours. Importantly, add them before the asset's own exports so that wildcard exports get
// correctly overwritten by own exports of the same name.
for (let dep of deps) {
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
if (dep.isOptional || this.bundleGraph.isDependencySkipped(dep)) {
continue;
}
let isWrapped = resolved && resolved.meta.shouldWrap;
for (let [imported, {
local
}] of dep.symbols) {
if (imported === '*' && local === '*') {
if (!resolved) {
// Re-exporting an external module. This should have already been handled in buildReplacements.
let external = (0, _nullthrows().default)((0, _nullthrows().default)(this.externals.get(dep.specifier)).get('*'));
append += `$parcel$exportWildcard($${assetId}$exports, ${external});\n`;
this.usedHelpers.add('$parcel$exportWildcard');
continue;
}
// If the resolved asset has an exports object, use the $parcel$exportWildcard helper
// to re-export all symbols. Otherwise, if there's no namespace object available, add
// $parcel$export calls for each used symbol of the dependency.
if (isWrapped || resolved.meta.staticExports === false || (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(resolved)).has('*') ||
// an empty asset
!resolved.meta.hasCJSExports && resolved.symbols.hasExportSymbol('*')) {
let obj = this.getSymbolResolution(asset, resolved, '*', dep);
append += `$parcel$exportWildcard($${assetId}$exports, ${obj});\n`;
this.usedHelpers.add('$parcel$exportWildcard');
} else {
for (let symbol of (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep))) {
if (symbol === 'default' ||
// `export * as ...` does not include the default export
symbol === '__esModule') {
continue;
}
let resolvedSymbol = this.getSymbolResolution(asset, resolved, symbol);
let get = this.buildFunctionExpression([], resolvedSymbol);
let set = asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolvedSymbol} = v`) : '';
prepend += `$parcel$export($${assetId}$exports, ${JSON.stringify(symbol)}, ${get}${set});\n`;
this.usedHelpers.add('$parcel$export');
prependLineCount++;
}
}
}
}
}
// Find the used exports of this module. This is based on the used symbols of
// incoming dependencies rather than the asset's own used exports so that we include
// re-exported symbols rather than only symbols declared in this asset.
let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
if (symbol === '*') {
return false;
}
// If we need default interop, then all symbols are needed because the `default`
// symbol really maps to the whole namespace.
if (defaultInterop) {
return true;
}
let unused = incomingDeps.every(d => {
let symbols = (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(d));
return !symbols.has(symbol) && !symbols.has('*');
});
return !unused;
});
if (usedExports.length > 0) {
// Insert $parcel$export calls for each of the used exports. This creates a getter/setter
// for the symbol so that when the value changes the object property also changes. This is
// required to simulate ESM live bindings. It's easier to do it this way rather than inserting
// additional assignments after each mutation of the original binding.
prepend += `\n${usedExports.map(exp => {
var _asset$symbols$get2;
let resolved = this.getSymbolResolution(asset, asset, exp);
let get = this.buildFunctionExpression([], resolved);
let isEsmExport = !!((_asset$symbols$get2 = asset.symbols.get(exp)) !== null && _asset$symbols$get2 !== void 0 && (_asset$symbols$get2 = _asset$symbols$get2.meta) !== null && _asset$symbols$get2 !== void 0 && _asset$symbols$get2.isEsm);
let set = !isEsmExport && asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`) : '';
return `$parcel$export($${assetId}$exports, ${JSON.stringify(exp)}, ${get}${set});`;
}).join('\n')}\n`;
this.usedHelpers.add('$parcel$export');
prependLineCount += 1 + usedExports.length;
}
}
return [prepend, prependLineCount, append];
}
buildBundlePrelude() {
let enableSourceMaps = this.bundle.env.sourceMap;
let res = '';
let lines = 0;
// Add hashbang if the entry asset recorded an interpreter.
let mainEntry = this.bundle.getMainEntry();
if (mainEntry && !this.isAsyncBundle && !this.bundle.target.env.isBrowser()) {
let interpreter = mainEntry.meta.interpreter;
(0, _assert().default)(interpreter == null || typeof interpreter === 'string');
if (interpreter != null) {
res += `#!${interpreter}\n`;
lines++;
}
}
// The output format may have specific things to add at the start of the bundle (e.g. imports).
let [outputFormatPrelude, outputFormatLines] = this.outputFormat.buildBundlePrelude();
res += outputFormatPrelude;
lines += outputFormatLines;
// Add used helpers.
if (this.needsPrelude) {
this.usedHelpers.add('$parcel$global');
}
for (let helper of this.usedHelpers) {
let currentHelper = _helpers.helpers[helper];
if (typeof currentHelper === 'function') {
currentHelper = _helpers.helpers[helper](this.bundle.env);
}
res += currentHelper;
if (enableSourceMaps) {
lines += (0, _utils().countLines)(currentHelper) - 1;
}
}
if (this.needsPrelude) {
// Add the prelude if this is potentially the first JS bundle to load in a
// particular context (e.g. entry scripts in HTML, workers, etc.).
let parentBundles = this.bundleGraph.getParentBundles(this.bundle);
let mightBeFirstJS = parentBundles.length === 0 || parentBundles.some(b => b.type !== 'js') || this.bundleGraph.getBundleGroupsContainingBundle(this.bundle).some(g => this.bundleGraph.isEntryBundleGroup(g)) || this.bundle.env.isIsolated() || this.bundle.bundleBehavior === 'isolated';
if (mightBeFirstJS) {
let preludeCode = (0, _helpers.prelude)(this.parcelRequireName);
res += preludeCode;
if (enableSourceMaps) {
lines += (0, _utils().countLines)(preludeCode) - 1;
}
if (this.shouldBundleQueue(this.bundle)) {
let bundleQueuePreludeCode = (0, _helpers.bundleQueuePrelude)(this.bundle.env);
res += bundleQueuePreludeCode;
if (enableSourceMaps) {
lines += (0, _utils().countLines)(bundleQueuePreludeCode) - 1;
}
}
} else {
// Otherwise, get the current parcelRequire global.
const escaped = JSON.stringify(this.parcelRequireName);
res += `var parcelRequire = $parcel$global[${escaped}];\n`;
lines++;
res += `var parcelRegister = parcelRequire.register;\n`;
lines++;
}
}
// Add importScripts for sibling bundles in workers.
if (this.bundle.env.isWorker() || this.bundle.env.isWorklet()) {
let importScripts = '';
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
for (let b of bundles) {
if (this.bundle.env.outputFormat === 'esmodule') {
// importScripts() is not allowed in native ES module workers.
importScripts += `import "${(0, _utils().relativeBundlePath)(this.bundle, b)}";\n`;
} else {
importScripts += `importScripts("${(0, _utils().relativeBundlePath)(this.bundle, b)}");\n`;
}
}
res += importScripts;
lines += bundles.length;
}
return [res, lines];
}
needsDefaultInterop(asset) {
if (asset.symbols.hasExportSymbol('*') && !asset.symbols.hasExportSymbol('default')) {
let deps = this.bundleGraph.getIncomingDependencies(asset);
return deps.some(dep => this.bundle.hasDependency(dep) &&
// dep.meta.isES6Module &&
dep.symbols.hasExportSymbol('default'));
}
return false;
}
shouldSkipAsset(asset) {
if (this.isScriptEntry(asset)) {
return true;
}
return asset.sideEffects === false && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(asset)).size == 0 && !this.bundleGraph.isAssetReferenced(this.bundle, asset);
}
isScriptEntry(asset) {
return this.bundle.env.outputFormat === 'global' && this.bundle.env.sourceType === 'script' && asset === this.bundle.getMainEntry();
}
buildFunctionExpression(args, expr) {
return this.bundle.env.supports('arrow-functions', true) ? `(${args.join(', ')}) => ${expr}` : `function (${args.join(', ')}) { return ${expr}; }`;
}
}
exports.ScopeHoistingPackager = ScopeHoistingPackager;

View File

@@ -0,0 +1,145 @@
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
/* eslint-disable no-undef */
var globalObject =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
/* eslint-enable no-undef */
// Save the require from previous bundle to this closure if any
var previousRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
var cache = previousRequire.cache || {};
// Do not use `require` to prevent Webpack from trying to bundle this call
var nodeRequire =
typeof module !== 'undefined' &&
typeof module.require === 'function' &&
module.require.bind(module);
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}
var err = new Error("Cannot find module '" + name + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
localRequire.resolve = resolve;
localRequire.cache = {};
var module = (cache[name] = new newRequire.Module(name));
modules[name][0].call(
module.exports,
localRequire,
module,
module.exports,
this
);
}
return cache[name].exports;
function localRequire(x) {
var res = localRequire.resolve(x);
return res === false ? {} : newRequire(res);
}
function resolve(x) {
var id = modules[name][1][x];
return id != null ? id : x;
}
}
function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}
newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [
function (require, module) {
module.exports = exports;
},
{},
];
};
Object.defineProperty(newRequire, 'root', {
get: function () {
return globalObject[parcelRequireName];
},
});
globalObject[parcelRequireName] = newRequire;
for (var i = 0; i < entry.length; i++) {
newRequire(entry[i]);
}
if (mainEntry) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(mainEntry);
// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = mainExports;
// RequireJS
} else if (typeof define === 'function' && define.amd) {
define(function () {
return mainExports;
});
// <script>
} else if (globalName) {
this[globalName] = mainExports;
}
}
});

View File

@@ -0,0 +1,129 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.prelude = exports.helpers = exports.fnExpr = exports.bundleQueuePrelude = void 0;
const prelude = parcelRequireName => `
var $parcel$modules = {};
var $parcel$inits = {};
var parcelRequire = $parcel$global[${JSON.stringify(parcelRequireName)}];
if (parcelRequire == null) {
parcelRequire = function(id) {
if (id in $parcel$modules) {
return $parcel$modules[id].exports;
}
if (id in $parcel$inits) {
var init = $parcel$inits[id];
delete $parcel$inits[id];
var module = {id: id, exports: {}};
$parcel$modules[id] = module;
init.call(module.exports, module, module.exports);
return module.exports;
}
var err = new Error("Cannot find module '" + id + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
};
parcelRequire.register = function register(id, init) {
$parcel$inits[id] = init;
};
$parcel$global[${JSON.stringify(parcelRequireName)}] = parcelRequire;
}
var parcelRegister = parcelRequire.register;
`;
exports.prelude = prelude;
const fnExpr = (env, params, body) => {
let block = `{ ${body.join(' ')} }`;
if (env.supports('arrow-functions')) {
return `(${params.join(', ')}) => ${block}`;
}
return `function (${params.join(', ')}) ${block}`;
};
exports.fnExpr = fnExpr;
const bundleQueuePrelude = env => `
if (!$parcel$global.lb) {
// Set of loaded bundles
$parcel$global.lb = new Set();
// Queue of bundles to execute once they're dep bundles are loaded
$parcel$global.bq = [];
// Register loaded bundle
$parcel$global.rlb = ${fnExpr(env, ['bundle'], ['$parcel$global.lb.add(bundle);', '$parcel$global.pq();'])}
// Run when ready
$parcel$global.rwr = ${fnExpr(env,
// b = bundle public id
// r = run function to execute the bundle entry
// d = list of dependent bundles this bundle requires before executing
['b', 'r', 'd'], ['$parcel$global.bq.push({b, r, d});', '$parcel$global.pq();'])}
// Process queue
$parcel$global.pq = ${fnExpr(env, [], [`var runnableEntry = $parcel$global.bq.find(${fnExpr(env, ['i'], [`return i.d.every(${fnExpr(env, ['dep'], ['return $parcel$global.lb.has(dep);'])});`])});`, 'if (runnableEntry) {', `$parcel$global.bq = $parcel$global.bq.filter(${fnExpr(env, ['i'], ['return i.b !== runnableEntry.b;'])});`, 'runnableEntry.r();', '$parcel$global.pq();', '}'])}
}
`;
exports.bundleQueuePrelude = bundleQueuePrelude;
const $parcel$export = `
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
`;
const $parcel$exportWildcard = `
function $parcel$exportWildcard(dest, source) {
Object.keys(source).forEach(function(key) {
if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) {
return;
}
Object.defineProperty(dest, key, {
enumerable: true,
get: function get() {
return source[key];
}
});
});
return dest;
}
`;
const $parcel$interopDefault = `
function $parcel$interopDefault(a) {
return a && a.__esModule ? a.default : a;
}
`;
const $parcel$global = env => {
if (env.supports('global-this')) {
return `
var $parcel$global = globalThis;
`;
}
return `
var $parcel$global =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
`;
};
const $parcel$defineInteropFlag = `
function $parcel$defineInteropFlag(a) {
Object.defineProperty(a, '__esModule', {value: true, configurable: true});
}
`;
const helpers = exports.helpers = {
$parcel$export,
$parcel$exportWildcard,
$parcel$interopDefault,
$parcel$global,
$parcel$defineInteropFlag
};

View File

@@ -0,0 +1,146 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _plugin() {
const data = require("@parcel/plugin");
_plugin = function () {
return data;
};
return data;
}
function _utils() {
const data = require("@parcel/utils");
_utils = function () {
return data;
};
return data;
}
function _diagnostic() {
const data = require("@parcel/diagnostic");
_diagnostic = function () {
return data;
};
return data;
}
function _rust() {
const data = require("@parcel/rust");
_rust = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
var _DevPackager = require("./DevPackager");
var _ScopeHoistingPackager = require("./ScopeHoistingPackager");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const CONFIG_SCHEMA = {
type: 'object',
properties: {
unstable_asyncBundleRuntime: {
type: 'boolean'
}
},
additionalProperties: false
};
var _default = exports.default = new (_plugin().Packager)({
async loadConfig({
config,
options
}) {
var _pkg$contents$name, _pkg$contents, _pkg$contents$package;
// Generate a name for the global parcelRequire function that is unique to this project.
// This allows multiple parcel builds to coexist on the same page.
let pkg = await config.getConfigFrom(_path().default.join(options.projectRoot, 'index'), ['package.json']);
let packageKey = '@parcel/packager-js';
if (pkg !== null && pkg !== void 0 && pkg.contents[packageKey]) {
_utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
data: pkg === null || pkg === void 0 ? void 0 : pkg.contents[packageKey],
source: await options.inputFS.readFile(pkg.filePath, 'utf8'),
filePath: pkg.filePath,
prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)(packageKey)}`
}, packageKey, `Invalid config for ${packageKey}`);
}
let name = (_pkg$contents$name = pkg === null || pkg === void 0 || (_pkg$contents = pkg.contents) === null || _pkg$contents === void 0 ? void 0 : _pkg$contents.name) !== null && _pkg$contents$name !== void 0 ? _pkg$contents$name : '';
return {
parcelRequireName: 'parcelRequire' + (0, _rust().hashString)(name).slice(-4),
unstable_asyncBundleRuntime: Boolean(pkg === null || pkg === void 0 || (_pkg$contents$package = pkg.contents[packageKey]) === null || _pkg$contents$package === void 0 ? void 0 : _pkg$contents$package.unstable_asyncBundleRuntime)
};
},
async package({
bundle,
bundleGraph,
getInlineBundleContents,
getSourceMapReference,
config,
options
}) {
// If this is a non-module script, and there is only one asset with no dependencies,
// then we don't need to package at all and can pass through the original code un-wrapped.
let contents, map;
if (bundle.env.sourceType === 'script') {
let entries = bundle.getEntryAssets();
if (entries.length === 1 && bundleGraph.getDependencies(entries[0]).length === 0) {
contents = await entries[0].getCode();
map = await entries[0].getMap();
}
}
if (contents == null) {
let packager = bundle.env.shouldScopeHoist ? new _ScopeHoistingPackager.ScopeHoistingPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName, (0, _nullthrows().default)(config).unstable_asyncBundleRuntime) : new _DevPackager.DevPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName);
({
contents,
map
} = await packager.package());
}
contents += '\n' + (await getSourceMapSuffix(getSourceMapReference, map));
// For library builds, we need to replace URL references with their final resolved paths.
// For non-library builds, this is handled in the JS runtime.
if (bundle.env.isLibrary) {
({
contents,
map
} = (0, _utils().replaceURLReferences)({
bundle,
bundleGraph,
contents,
map,
getReplacement: s => JSON.stringify(s).slice(1, -1)
}));
}
return (0, _utils().replaceInlineReferences)({
bundle,
bundleGraph,
contents,
getInlineReplacement: (dependency, inlineType, content) => ({
from: `"${dependency.id}"`,
to: inlineType === 'string' ? JSON.stringify(content) : content
}),
getInlineBundleContents,
map
});
}
});
async function getSourceMapSuffix(getSourceMapReference, map) {
let sourcemapReference = await getSourceMapReference(map);
if (sourcemapReference != null) {
return '//# sourceMappingURL=' + sourcemapReference + '\n';
} else {
return '';
}
}

View File

@@ -0,0 +1,51 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getSpecifier = getSpecifier;
exports.replaceScriptDependencies = replaceScriptDependencies;
function _nullthrows() {
const data = _interopRequireDefault(require("nullthrows"));
_nullthrows = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// This replaces __parcel__require__ references left by the transformer with
// parcelRequire calls of the resolved asset id. This lets runtimes work within
// script bundles, which must be outside the bundle wrapper so their variables are global.
function replaceScriptDependencies(bundleGraph, bundle, code, map, parcelRequireName) {
let entry = (0, _nullthrows().default)(bundle.getMainEntry());
let dependencies = bundleGraph.getDependencies(entry);
let lineCount = 0;
let offset = 0;
let columnStartIndex = 0;
code = code.replace(/\n|__parcel__require__\(['"](.*?)['"]\)/g, (m, s, i) => {
if (m === '\n') {
columnStartIndex = i + offset + 1;
lineCount++;
return '\n';
}
let dep = (0, _nullthrows().default)(dependencies.find(d => getSpecifier(d) === s));
let resolved = (0, _nullthrows().default)(bundleGraph.getResolvedAsset(dep, bundle));
let publicId = bundleGraph.getAssetPublicId(resolved);
let replacement = `${parcelRequireName}("${publicId}")`;
if (map) {
let lengthDifference = replacement.length - m.length;
if (lengthDifference !== 0) {
map.offsetColumns(lineCount + 1, i + offset - columnStartIndex + m.length, lengthDifference);
offset += lengthDifference;
}
}
return replacement;
});
return code;
}
function getSpecifier(dep) {
if (typeof dep.meta.placeholder === 'string') {
return dep.meta.placeholder;
}
return dep.specifier;
}

View File

@@ -0,0 +1,33 @@
{
"name": "@parcel/packager-js",
"version": "2.12.0",
"license": "MIT",
"publishConfig": {
"access": "public"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"repository": {
"type": "git",
"url": "https://github.com/parcel-bundler/parcel.git"
},
"main": "lib/index.js",
"source": "src/index.js",
"engines": {
"node": ">= 12.0.0",
"parcel": "^2.12.0"
},
"dependencies": {
"@parcel/diagnostic": "2.12.0",
"@parcel/plugin": "2.12.0",
"@parcel/rust": "2.12.0",
"@parcel/source-map": "^2.1.1",
"@parcel/types": "2.12.0",
"@parcel/utils": "2.12.0",
"globals": "^13.2.0",
"nullthrows": "^1.1.1"
},
"gitHead": "2059029ee91e5f03a273b0954d3e629d7375f986"
}

View File

@@ -0,0 +1,13 @@
{
"extends": "@parcel/eslint-config",
"overrides": [
{
"files": ["dev-prelude.js"],
"parser": "espree",
"parserOptions": {
"ecmaVersion": 5,
"sourceType": "script"
}
}
]
}

View File

@@ -0,0 +1,42 @@
// @flow
import type {
ScopeHoistingPackager,
OutputFormat,
} from './ScopeHoistingPackager';
export class CJSOutputFormat implements OutputFormat {
packager: ScopeHoistingPackager;
constructor(packager: ScopeHoistingPackager) {
this.packager = packager;
}
buildBundlePrelude(): [string, number] {
let res = '';
let lines = 0;
for (let [source, specifiers] of this.packager.externals) {
// CJS only supports the namespace symbol. This ensures that all accesses
// are live and the `this` binding is correct.
let namespace = specifiers.get('*');
if (namespace) {
res += `var ${namespace} = require(${JSON.stringify(source)});\n`;
lines++;
} else {
res += `require(${JSON.stringify(source)});\n`;
lines++;
}
}
if (res.length > 0) {
res += '\n';
lines++;
}
return [res, lines];
}
buildBundlePostlude(): [string, number] {
return ['', 0];
}
}

View File

@@ -0,0 +1,252 @@
// @flow strict-local
import type {BundleGraph, PluginOptions, NamedBundle} from '@parcel/types';
import {
PromiseQueue,
relativeBundlePath,
countLines,
normalizeSeparators,
} from '@parcel/utils';
import SourceMap from '@parcel/source-map';
import invariant from 'assert';
import path from 'path';
import fs from 'fs';
import {replaceScriptDependencies, getSpecifier} from './utils';
const PRELUDE = fs
.readFileSync(path.join(__dirname, 'dev-prelude.js'), 'utf8')
.trim()
.replace(/;$/, '');
export class DevPackager {
options: PluginOptions;
bundleGraph: BundleGraph<NamedBundle>;
bundle: NamedBundle;
parcelRequireName: string;
constructor(
options: PluginOptions,
bundleGraph: BundleGraph<NamedBundle>,
bundle: NamedBundle,
parcelRequireName: string,
) {
this.options = options;
this.bundleGraph = bundleGraph;
this.bundle = bundle;
this.parcelRequireName = parcelRequireName;
}
async package(): Promise<{|contents: string, map: ?SourceMap|}> {
// Load assets
let queue = new PromiseQueue({maxConcurrent: 32});
this.bundle.traverseAssets(asset => {
queue.add(async () => {
let [code, mapBuffer] = await Promise.all([
asset.getCode(),
this.bundle.env.sourceMap && asset.getMapBuffer(),
]);
return {code, mapBuffer};
});
});
let results = await queue.run();
let assets = '';
let i = 0;
let first = true;
let map = new SourceMap(this.options.projectRoot);
let prefix = this.getPrefix();
let lineOffset = countLines(prefix);
let script: ?{|code: string, mapBuffer: ?Buffer|} = null;
this.bundle.traverse(node => {
let wrapped = first ? '' : ',';
if (node.type === 'dependency') {
let resolved = this.bundleGraph.getResolvedAsset(
node.value,
this.bundle,
);
if (resolved && resolved.type !== 'js') {
// if this is a reference to another javascript asset, we should not include
// its output, as its contents should already be loaded.
invariant(!this.bundle.hasAsset(resolved));
wrapped +=
JSON.stringify(this.bundleGraph.getAssetPublicId(resolved)) +
':[function() {},{}]';
} else {
return;
}
}
if (node.type === 'asset') {
let asset = node.value;
invariant(
asset.type === 'js',
'all assets in a js bundle must be js assets',
);
// If this is the main entry of a script rather than a module, we need to hoist it
// outside the bundle wrapper function so that its variables are exposed as globals.
if (
this.bundle.env.sourceType === 'script' &&
asset === this.bundle.getMainEntry()
) {
script = results[i++];
return;
}
let deps = {};
let dependencies = this.bundleGraph.getDependencies(asset);
for (let dep of dependencies) {
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
if (this.bundleGraph.isDependencySkipped(dep)) {
deps[getSpecifier(dep)] = false;
} else if (resolved) {
deps[getSpecifier(dep)] =
this.bundleGraph.getAssetPublicId(resolved);
} else {
// An external module - map placeholder to original specifier.
deps[getSpecifier(dep)] = dep.specifier;
}
}
let {code, mapBuffer} = results[i];
let output = code || '';
wrapped +=
JSON.stringify(this.bundleGraph.getAssetPublicId(asset)) +
':[function(require,module,exports) {\n' +
output +
'\n},';
wrapped += JSON.stringify(deps);
wrapped += ']';
if (
this.bundle.env.isNode() &&
asset.meta.has_node_replacements === true
) {
const relPath = normalizeSeparators(
path.relative(
this.bundle.target.distDir,
path.dirname(asset.filePath),
),
);
wrapped = wrapped.replace('$parcel$dirnameReplace', relPath);
wrapped = wrapped.replace('$parcel$filenameReplace', relPath);
}
if (this.bundle.env.sourceMap) {
if (mapBuffer) {
map.addBuffer(mapBuffer, lineOffset);
} else {
map.addEmptyMap(
path
.relative(this.options.projectRoot, asset.filePath)
.replace(/\\+/g, '/'),
output,
lineOffset,
);
}
lineOffset += countLines(output) + 1;
}
i++;
}
assets += wrapped;
first = false;
});
let entries = this.bundle.getEntryAssets();
let mainEntry = this.bundle.getMainEntry();
if (
(!this.isEntry() && this.bundle.env.outputFormat === 'global') ||
this.bundle.env.sourceType === 'script'
) {
// In async bundles we don't want the main entry to execute until we require it
// as there might be dependencies in a sibling bundle that hasn't loaded yet.
entries = entries.filter(a => a.id !== mainEntry?.id);
mainEntry = null;
}
let contents =
prefix +
'({' +
assets +
'},' +
JSON.stringify(
entries.map(asset => this.bundleGraph.getAssetPublicId(asset)),
) +
', ' +
JSON.stringify(
mainEntry ? this.bundleGraph.getAssetPublicId(mainEntry) : null,
) +
', ' +
JSON.stringify(this.parcelRequireName) +
')' +
'\n';
// The entry asset of a script bundle gets hoisted outside the bundle wrapper function
// so that its variables become globals. We need to replace any require calls for
// runtimes with a parcelRequire call.
if (this.bundle.env.sourceType === 'script' && script) {
let entryMap;
let mapBuffer = script.mapBuffer;
if (mapBuffer) {
entryMap = new SourceMap(this.options.projectRoot, mapBuffer);
}
contents += replaceScriptDependencies(
this.bundleGraph,
this.bundle,
script.code,
entryMap,
this.parcelRequireName,
);
if (this.bundle.env.sourceMap && entryMap) {
map.addSourceMap(entryMap, lineOffset);
}
}
return {
contents,
map,
};
}
getPrefix(): string {
let interpreter: ?string;
let mainEntry = this.bundle.getMainEntry();
if (mainEntry && this.isEntry() && !this.bundle.target.env.isBrowser()) {
let _interpreter = mainEntry.meta.interpreter;
invariant(_interpreter == null || typeof _interpreter === 'string');
interpreter = _interpreter;
}
let importScripts = '';
if (this.bundle.env.isWorker()) {
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
for (let b of bundles) {
importScripts += `importScripts("${relativeBundlePath(
this.bundle,
b,
)}");\n`;
}
}
return (
// If the entry asset included a hashbang, repeat it at the top of the bundle
(interpreter != null ? `#!${interpreter}\n` : '') +
importScripts +
PRELUDE
);
}
isEntry(): boolean {
return (
!this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') ||
this.bundle.env.isIsolated() ||
this.bundle.bundleBehavior === 'isolated'
);
}
}

View File

@@ -0,0 +1,122 @@
// @flow
import type {
ScopeHoistingPackager,
OutputFormat,
} from './ScopeHoistingPackager';
export class ESMOutputFormat implements OutputFormat {
packager: ScopeHoistingPackager;
constructor(packager: ScopeHoistingPackager) {
this.packager = packager;
}
buildBundlePrelude(): [string, number] {
let res = '';
let lines = 0;
for (let [source, specifiers] of this.packager.externals) {
let defaultSpecifier = null;
let namespaceSpecifier = null;
let namedSpecifiers = [];
for (let [imported, symbol] of specifiers) {
if (imported === 'default' /* || isCommonJS*/) {
defaultSpecifier = symbol;
} else if (imported === '*') {
namespaceSpecifier = `* as ${symbol}`;
} else {
let specifier = imported;
if (symbol !== imported) {
specifier += ` as ${symbol}`;
}
namedSpecifiers.push(specifier);
}
}
// ESModule syntax allows combining default and namespace specifiers, or default and named, but not all three.
let imported = '';
if (namespaceSpecifier) {
let s = namespaceSpecifier;
if (defaultSpecifier) {
s = `${defaultSpecifier}, ${namespaceSpecifier}`;
}
res += `import ${s} from ${JSON.stringify(source)};\n`;
lines++;
} else if (defaultSpecifier) {
imported = defaultSpecifier;
if (namedSpecifiers.length > 0) {
imported += `, {${namedSpecifiers.join(', ')}}`;
}
} else if (namedSpecifiers.length > 0) {
imported = `{${namedSpecifiers.join(', ')}}`;
}
if (imported.length > 0) {
res += `import ${imported} from ${JSON.stringify(source)};\n`;
lines++;
} else if (!namespaceSpecifier) {
res += `import ${JSON.stringify(source)};\n`;
lines++;
}
}
if (res.length > 0) {
res += '\n';
lines++;
}
return [res, lines];
}
buildBundlePostlude(): [string, number] {
let res = '';
let lines = 0;
let exportSpecifiers = [];
for (let {
asset,
exportSymbol,
local,
exportAs,
} of this.packager.exportedSymbols.values()) {
if (this.packager.wrappedAssets.has(asset.id)) {
let obj = `parcelRequire("${this.packager.bundleGraph.getAssetPublicId(
asset,
)}")`;
res += `\nvar ${local} = ${this.packager.getPropertyAccess(
obj,
exportSymbol,
)};`;
lines++;
}
for (let as of exportAs) {
let specifier = local;
if (exportAs !== local) {
specifier += ` as ${as}`;
}
exportSpecifiers.push(specifier);
}
}
if (exportSpecifiers.length > 0) {
res += `\nexport {${exportSpecifiers.join(', ')}};`;
lines++;
}
if (
this.packager.needsPrelude &&
this.packager.shouldBundleQueue(this.packager.bundle)
) {
// Should be last thing the bundle executes on intial eval
res += `\n$parcel$global.rlb(${JSON.stringify(
this.packager.bundle.publicId,
)})`;
lines++;
}
return [res, lines];
}
}

View File

@@ -0,0 +1,24 @@
// @flow
import type {
ScopeHoistingPackager,
OutputFormat,
} from './ScopeHoistingPackager';
export class GlobalOutputFormat implements OutputFormat {
packager: ScopeHoistingPackager;
constructor(packager: ScopeHoistingPackager) {
this.packager = packager;
}
buildBundlePrelude(): [string, number] {
let prelude = this.packager.bundle.env.supports('arrow-functions', true)
? '(() => {\n'
: '(function () {\n';
return [prelude, 1];
}
buildBundlePostlude(): [string, number] {
return ['})();', 0];
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
// modules are defined as an array
// [ module function, map of requires ]
//
// map of requires is short require name -> numeric require
//
// anything defined in a previous bundle is accessed via the
// orig method which is the require for previous bundles
(function (modules, entry, mainEntry, parcelRequireName, globalName) {
/* eslint-disable no-undef */
var globalObject =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
/* eslint-enable no-undef */
// Save the require from previous bundle to this closure if any
var previousRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
var cache = previousRequire.cache || {};
// Do not use `require` to prevent Webpack from trying to bundle this call
var nodeRequire =
typeof module !== 'undefined' &&
typeof module.require === 'function' &&
module.require.bind(module);
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire =
typeof globalObject[parcelRequireName] === 'function' &&
globalObject[parcelRequireName];
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}
var err = new Error("Cannot find module '" + name + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
}
localRequire.resolve = resolve;
localRequire.cache = {};
var module = (cache[name] = new newRequire.Module(name));
modules[name][0].call(
module.exports,
localRequire,
module,
module.exports,
this
);
}
return cache[name].exports;
function localRequire(x) {
var res = localRequire.resolve(x);
return res === false ? {} : newRequire(res);
}
function resolve(x) {
var id = modules[name][1][x];
return id != null ? id : x;
}
}
function Module(moduleName) {
this.id = moduleName;
this.bundle = newRequire;
this.exports = {};
}
newRequire.isParcelRequire = true;
newRequire.Module = Module;
newRequire.modules = modules;
newRequire.cache = cache;
newRequire.parent = previousRequire;
newRequire.register = function (id, exports) {
modules[id] = [
function (require, module) {
module.exports = exports;
},
{},
];
};
Object.defineProperty(newRequire, 'root', {
get: function () {
return globalObject[parcelRequireName];
},
});
globalObject[parcelRequireName] = newRequire;
for (var i = 0; i < entry.length; i++) {
newRequire(entry[i]);
}
if (mainEntry) {
// Expose entry point to Node, AMD or browser globals
// Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
var mainExports = newRequire(mainEntry);
// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = mainExports;
// RequireJS
} else if (typeof define === 'function' && define.amd) {
define(function () {
return mainExports;
});
// <script>
} else if (globalName) {
this[globalName] = mainExports;
}
}
});

View File

@@ -0,0 +1,169 @@
// @flow strict-local
import type {Environment} from '@parcel/types';
export const prelude = (parcelRequireName: string): string => `
var $parcel$modules = {};
var $parcel$inits = {};
var parcelRequire = $parcel$global[${JSON.stringify(parcelRequireName)}];
if (parcelRequire == null) {
parcelRequire = function(id) {
if (id in $parcel$modules) {
return $parcel$modules[id].exports;
}
if (id in $parcel$inits) {
var init = $parcel$inits[id];
delete $parcel$inits[id];
var module = {id: id, exports: {}};
$parcel$modules[id] = module;
init.call(module.exports, module, module.exports);
return module.exports;
}
var err = new Error("Cannot find module '" + id + "'");
err.code = 'MODULE_NOT_FOUND';
throw err;
};
parcelRequire.register = function register(id, init) {
$parcel$inits[id] = init;
};
$parcel$global[${JSON.stringify(parcelRequireName)}] = parcelRequire;
}
var parcelRegister = parcelRequire.register;
`;
export const fnExpr = (
env: Environment,
params: Array<string>,
body: Array<string>,
): string => {
let block = `{ ${body.join(' ')} }`;
if (env.supports('arrow-functions')) {
return `(${params.join(', ')}) => ${block}`;
}
return `function (${params.join(', ')}) ${block}`;
};
export const bundleQueuePrelude = (env: Environment): string => `
if (!$parcel$global.lb) {
// Set of loaded bundles
$parcel$global.lb = new Set();
// Queue of bundles to execute once they're dep bundles are loaded
$parcel$global.bq = [];
// Register loaded bundle
$parcel$global.rlb = ${fnExpr(
env,
['bundle'],
['$parcel$global.lb.add(bundle);', '$parcel$global.pq();'],
)}
// Run when ready
$parcel$global.rwr = ${fnExpr(
env,
// b = bundle public id
// r = run function to execute the bundle entry
// d = list of dependent bundles this bundle requires before executing
['b', 'r', 'd'],
['$parcel$global.bq.push({b, r, d});', '$parcel$global.pq();'],
)}
// Process queue
$parcel$global.pq = ${fnExpr(
env,
[],
[
`var runnableEntry = $parcel$global.bq.find(${fnExpr(
env,
['i'],
[
`return i.d.every(${fnExpr(
env,
['dep'],
['return $parcel$global.lb.has(dep);'],
)});`,
],
)});`,
'if (runnableEntry) {',
`$parcel$global.bq = $parcel$global.bq.filter(${fnExpr(
env,
['i'],
['return i.b !== runnableEntry.b;'],
)});`,
'runnableEntry.r();',
'$parcel$global.pq();',
'}',
],
)}
}
`;
const $parcel$export = `
function $parcel$export(e, n, v, s) {
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
}
`;
const $parcel$exportWildcard = `
function $parcel$exportWildcard(dest, source) {
Object.keys(source).forEach(function(key) {
if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) {
return;
}
Object.defineProperty(dest, key, {
enumerable: true,
get: function get() {
return source[key];
}
});
});
return dest;
}
`;
const $parcel$interopDefault = `
function $parcel$interopDefault(a) {
return a && a.__esModule ? a.default : a;
}
`;
const $parcel$global = (env: Environment): string => {
if (env.supports('global-this')) {
return `
var $parcel$global = globalThis;
`;
}
return `
var $parcel$global =
typeof globalThis !== 'undefined'
? globalThis
: typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: {};
`;
};
const $parcel$defineInteropFlag = `
function $parcel$defineInteropFlag(a) {
Object.defineProperty(a, '__esModule', {value: true, configurable: true});
}
`;
export const helpers = {
$parcel$export,
$parcel$exportWildcard,
$parcel$interopDefault,
$parcel$global,
$parcel$defineInteropFlag,
};

View File

@@ -0,0 +1,145 @@
// @flow strict-local
import type {Async} from '@parcel/types';
import type SourceMap from '@parcel/source-map';
import {Packager} from '@parcel/plugin';
import {
replaceInlineReferences,
replaceURLReferences,
validateSchema,
type SchemaEntity,
} from '@parcel/utils';
import {encodeJSONKeyComponent} from '@parcel/diagnostic';
import {hashString} from '@parcel/rust';
import path from 'path';
import nullthrows from 'nullthrows';
import {DevPackager} from './DevPackager';
import {ScopeHoistingPackager} from './ScopeHoistingPackager';
type JSPackagerConfig = {|
parcelRequireName: string,
unstable_asyncBundleRuntime: boolean,
|};
const CONFIG_SCHEMA: SchemaEntity = {
type: 'object',
properties: {
unstable_asyncBundleRuntime: {
type: 'boolean',
},
},
additionalProperties: false,
};
export default (new Packager({
async loadConfig({config, options}): Promise<JSPackagerConfig> {
// Generate a name for the global parcelRequire function that is unique to this project.
// This allows multiple parcel builds to coexist on the same page.
let pkg = await config.getConfigFrom(
path.join(options.projectRoot, 'index'),
['package.json'],
);
let packageKey = '@parcel/packager-js';
if (pkg?.contents[packageKey]) {
validateSchema.diagnostic(
CONFIG_SCHEMA,
{
data: pkg?.contents[packageKey],
source: await options.inputFS.readFile(pkg.filePath, 'utf8'),
filePath: pkg.filePath,
prependKey: `/${encodeJSONKeyComponent(packageKey)}`,
},
packageKey,
`Invalid config for ${packageKey}`,
);
}
let name = pkg?.contents?.name ?? '';
return {
parcelRequireName: 'parcelRequire' + hashString(name).slice(-4),
unstable_asyncBundleRuntime: Boolean(
pkg?.contents[packageKey]?.unstable_asyncBundleRuntime,
),
};
},
async package({
bundle,
bundleGraph,
getInlineBundleContents,
getSourceMapReference,
config,
options,
}) {
// If this is a non-module script, and there is only one asset with no dependencies,
// then we don't need to package at all and can pass through the original code un-wrapped.
let contents, map;
if (bundle.env.sourceType === 'script') {
let entries = bundle.getEntryAssets();
if (
entries.length === 1 &&
bundleGraph.getDependencies(entries[0]).length === 0
) {
contents = await entries[0].getCode();
map = await entries[0].getMap();
}
}
if (contents == null) {
let packager = bundle.env.shouldScopeHoist
? new ScopeHoistingPackager(
options,
bundleGraph,
bundle,
nullthrows(config).parcelRequireName,
nullthrows(config).unstable_asyncBundleRuntime,
)
: new DevPackager(
options,
bundleGraph,
bundle,
nullthrows(config).parcelRequireName,
);
({contents, map} = await packager.package());
}
contents += '\n' + (await getSourceMapSuffix(getSourceMapReference, map));
// For library builds, we need to replace URL references with their final resolved paths.
// For non-library builds, this is handled in the JS runtime.
if (bundle.env.isLibrary) {
({contents, map} = replaceURLReferences({
bundle,
bundleGraph,
contents,
map,
getReplacement: s => JSON.stringify(s).slice(1, -1),
}));
}
return replaceInlineReferences({
bundle,
bundleGraph,
contents,
getInlineReplacement: (dependency, inlineType, content) => ({
from: `"${dependency.id}"`,
to: inlineType === 'string' ? JSON.stringify(content) : content,
}),
getInlineBundleContents,
map,
});
},
}): Packager);
async function getSourceMapSuffix(
getSourceMapReference: (?SourceMap) => Async<?string>,
map: ?SourceMap,
): Promise<string> {
let sourcemapReference = await getSourceMapReference(map);
if (sourcemapReference != null) {
return '//# sourceMappingURL=' + sourcemapReference + '\n';
} else {
return '';
}
}

View File

@@ -0,0 +1,57 @@
// @flow
import type {BundleGraph, Dependency, NamedBundle} from '@parcel/types';
import type SourceMap from '@parcel/source-map';
import nullthrows from 'nullthrows';
// This replaces __parcel__require__ references left by the transformer with
// parcelRequire calls of the resolved asset id. This lets runtimes work within
// script bundles, which must be outside the bundle wrapper so their variables are global.
export function replaceScriptDependencies(
bundleGraph: BundleGraph<NamedBundle>,
bundle: NamedBundle,
code: string,
map: ?SourceMap,
parcelRequireName: string,
): string {
let entry = nullthrows(bundle.getMainEntry());
let dependencies = bundleGraph.getDependencies(entry);
let lineCount = 0;
let offset = 0;
let columnStartIndex = 0;
code = code.replace(/\n|__parcel__require__\(['"](.*?)['"]\)/g, (m, s, i) => {
if (m === '\n') {
columnStartIndex = i + offset + 1;
lineCount++;
return '\n';
}
let dep = nullthrows(dependencies.find(d => getSpecifier(d) === s));
let resolved = nullthrows(bundleGraph.getResolvedAsset(dep, bundle));
let publicId = bundleGraph.getAssetPublicId(resolved);
let replacement = `${parcelRequireName}("${publicId}")`;
if (map) {
let lengthDifference = replacement.length - m.length;
if (lengthDifference !== 0) {
map.offsetColumns(
lineCount + 1,
i + offset - columnStartIndex + m.length,
lengthDifference,
);
offset += lengthDifference;
}
}
return replacement;
});
return code;
}
export function getSpecifier(dep: Dependency): string {
if (typeof dep.meta.placeholder === 'string') {
return dep.meta.placeholder;
}
return dep.specifier;
}