diff --git a/History.md b/History.md index 36c6f5765f..d97cae081c 100644 --- a/History.md +++ b/History.md @@ -13,12 +13,28 @@ N/A * The `npm` npm package has been updated to version 6.9.2. +* When bundling client code, the Meteor module system now prefers the + `"module"` field in `package.json`, if defined. + [PR #10541](https://github.com/meteor/meteor/pull/10541) + +* ECMAScript module syntax (`import`, `export`, and dynamic `import()`) is + now supported by default everywhere, including in modules imported from + `node_modules`, thanks to the [Reify](https://github.com/benjamn/reify) + compiler. + +* If you need to import code from `node_modules` that uses modern syntax + beyond module syntax, it is now possible to enable recompilation for + specific npm packages using the `meteor.nodeModules.recompile` option in + your application's `package.json` file. + See [PR #10603](https://github.com/meteor/meteor/pull/10603) for further + explanation. + * The `mongodb` npm package used by the `npm-mongo` Meteor package has been updated to version 3.2.7. -* The `meteor-babel` npm package has been updated to version 7.4.15. +* The `meteor-babel` npm package has been updated to version 7.4.18. -* The `reify` npm package has been updated to version 0.20.6. +* The `reify` npm package has been updated to version 0.20.10. * The `core-js` npm package used by `ecmascript-runtime-client` and `ecmascript-runtime-server` has been updated to version 3.1.4. @@ -31,13 +47,6 @@ N/A * The `pathwatcher` npm package has been updated to version 8.1.0. -* When bundling client code, the Meteor module system now prefers the - `"module"` field in `package.json`, if defined. Additionally, npm - packages with a `"module"` entry point will now be compiled - automatically by `meteor-babel`, like application code, without any - special symlinking tricks. - [PR #10541](https://github.com/meteor/meteor/pull/10541) - * In addition to the `.js` and `.jsx` file extensions, the `ecmascript` compiler plugin now automatically handles JavaScript modules with the `.mjs` file extension. diff --git a/meteor b/meteor index ee6f9cb66c..c4f339fc96 100755 --- a/meteor +++ b/meteor @@ -1,6 +1,6 @@ #!/usr/bin/env bash -BUNDLE_VERSION=8.16.0.12 +BUNDLE_VERSION=8.16.0.14 # OS Check. Put here because here is where we download the precompiled # bundles that are arch specific. diff --git a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json index 084914105a..04ed83cc3b 100644 --- a/packages/babel-compiler/.npm/package/npm-shrinkwrap.json +++ b/packages/babel-compiler/.npm/package/npm-shrinkwrap.json @@ -603,10 +603,15 @@ "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==" + }, "meteor-babel": { - "version": "7.4.15", - "resolved": "https://registry.npmjs.org/meteor-babel/-/meteor-babel-7.4.15.tgz", - "integrity": "sha512-1HYThnReelvxW31ry5rZVTdvNqml8+JDsZYvvOjc2pIaMmo/6e3VlPU3Jv3hoYRDjxOO9OTohvWewfu6j0o+XA==" + "version": "7.4.18", + "resolved": "https://registry.npmjs.org/meteor-babel/-/meteor-babel-7.4.18.tgz", + "integrity": "sha512-7nJgy09paSOMlZFonv2qb6nUOiAtYXcg+fN+v/npZ7ToMPCqaLavzjjPj8PMvw7KxcdSBFw+52YVw6XFKm2zcQ==" }, "meteor-babel-helpers": { "version": "0.0.3", @@ -676,9 +681,9 @@ } }, "reify": { - "version": "0.20.6", - "resolved": "https://registry.npmjs.org/reify/-/reify-0.20.6.tgz", - "integrity": "sha512-kCgL6HyzFBK3fIKwurPn0O4+mzdK4R4uOYyQxXaYm4B+QgrQ1EHiQ222qsLPEhB1ReBRh+njO0I4kw7hCGfM2w==" + "version": "0.20.10", + "resolved": "https://registry.npmjs.org/reify/-/reify-0.20.10.tgz", + "integrity": "sha512-+6mRLK2UA0BrdygnkZvJqc5Z+nktfnT/AuzrtwzMnHXc/2oaPr8LmNai29C193SL3tulMBeVPXzhkRQJs/cjTg==" }, "resolve": { "version": "1.11.1", @@ -700,6 +705,11 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, + "sourcemap-codec": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", + "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/packages/babel-compiler/package.js b/packages/babel-compiler/package.js index 38911141e9..116507a3da 100644 --- a/packages/babel-compiler/package.js +++ b/packages/babel-compiler/package.js @@ -6,11 +6,11 @@ Package.describe({ // isn't possible because you can't publish a non-recommended // release with package versions that don't have a pre-release // identifier at the end (eg, -dev) - version: '7.4.0-beta182.10' + version: '7.4.0-beta182.11' }); Npm.depends({ - 'meteor-babel': '7.4.15', + 'meteor-babel': '7.4.18', 'json5': '2.1.0' }); diff --git a/packages/babel-runtime/package.js b/packages/babel-runtime/package.js index 3ca647def6..0dcfef61c6 100644 --- a/packages/babel-runtime/package.js +++ b/packages/babel-runtime/package.js @@ -1,7 +1,7 @@ Package.describe({ name: "babel-runtime", summary: "Runtime support for output of Babel transpiler", - version: '1.4.0-beta182.10', + version: '1.4.0-beta182.11', documentation: 'README.md' }); diff --git a/packages/context/package.js b/packages/context/package.js index 3cc00fcf4f..6c8ae16863 100644 --- a/packages/context/package.js +++ b/packages/context/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "context", - version: "0.4.0-beta182.10", + version: "0.4.0-beta182.11", summary: "Manage contextual information without passing objects around", documentation: "README.md" }); diff --git a/packages/ecmascript-runtime-client/package.js b/packages/ecmascript-runtime-client/package.js index 0690bc49bd..5b0cd022ff 100644 --- a/packages/ecmascript-runtime-client/package.js +++ b/packages/ecmascript-runtime-client/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "ecmascript-runtime-client", - version: "0.9.0-beta182.10", + version: "0.9.0-beta182.11", summary: "Polyfills for new ECMAScript 2015 APIs like Map and Set", git: "https://github.com/meteor/meteor/tree/devel/packages/ecmascript-runtime-client", documentation: "README.md" diff --git a/packages/ecmascript-runtime-server/package.js b/packages/ecmascript-runtime-server/package.js index 5f8124a3da..4d0ca95c2d 100644 --- a/packages/ecmascript-runtime-server/package.js +++ b/packages/ecmascript-runtime-server/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "ecmascript-runtime-server", - version: "0.8.0-beta182.10", + version: "0.8.0-beta182.11", summary: "Polyfills for new ECMAScript 2015 APIs like Map and Set", git: "https://github.com/meteor/meteor/tree/devel/packages/ecmascript-runtime-client", documentation: "README.md" diff --git a/packages/ecmascript/ecmascript.js b/packages/ecmascript/ecmascript.js index 10d7a6b6f0..d562fc0df1 100644 --- a/packages/ecmascript/ecmascript.js +++ b/packages/ecmascript/ecmascript.js @@ -1,7 +1,8 @@ ECMAScript = { compileForShell(command, cacheOptions) { const babelOptions = Babel.getDefaultOptions({ - nodeMajorVersion: parseInt(process.versions.node, 10) + nodeMajorVersion: parseInt(process.versions.node, 10), + compileForShell: true }); delete babelOptions.sourceMap; delete babelOptions.sourceMaps; diff --git a/packages/ecmascript/package.js b/packages/ecmascript/package.js index c3a20732c5..29a5ffe5d5 100644 --- a/packages/ecmascript/package.js +++ b/packages/ecmascript/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'ecmascript', - version: '0.13.0-beta182.10', + version: '0.13.0-beta182.11', summary: 'Compiler plugin that supports ES2015+ in all .js files', documentation: 'README.md' }); diff --git a/packages/meteor-tool/package.js b/packages/meteor-tool/package.js index e5278ca25f..3acbba13a8 100644 --- a/packages/meteor-tool/package.js +++ b/packages/meteor-tool/package.js @@ -1,6 +1,6 @@ Package.describe({ summary: "The Meteor command-line tool", - version: '1.8.2-beta.10' + version: '1.8.2-beta.11' }); Package.includeTool(); diff --git a/packages/modules-runtime/package.js b/packages/modules-runtime/package.js index 0570b026ba..9d77750cbc 100644 --- a/packages/modules-runtime/package.js +++ b/packages/modules-runtime/package.js @@ -1,6 +1,6 @@ Package.describe({ name: "modules-runtime", - version: "0.11.0-beta182.10", + version: "0.11.0-beta182.11", summary: "CommonJS module system", git: "https://github.com/benjamn/install", documentation: "README.md" diff --git a/packages/modules/.npm/package/npm-shrinkwrap.json b/packages/modules/.npm/package/npm-shrinkwrap.json index ff9273bf41..4fe3730e78 100644 --- a/packages/modules/.npm/package/npm-shrinkwrap.json +++ b/packages/modules/.npm/package/npm-shrinkwrap.json @@ -11,20 +11,30 @@ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==" }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==" + }, "meteor-babel-helpers": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/meteor-babel-helpers/-/meteor-babel-helpers-0.0.3.tgz", "integrity": "sha1-8uXZ+HlvvS6JAQI9dpnlsgLqn7A=" }, "reify": { - "version": "0.20.6", - "resolved": "https://registry.npmjs.org/reify/-/reify-0.20.6.tgz", - "integrity": "sha512-kCgL6HyzFBK3fIKwurPn0O4+mzdK4R4uOYyQxXaYm4B+QgrQ1EHiQ222qsLPEhB1ReBRh+njO0I4kw7hCGfM2w==" + "version": "0.20.10", + "resolved": "https://registry.npmjs.org/reify/-/reify-0.20.10.tgz", + "integrity": "sha512-+6mRLK2UA0BrdygnkZvJqc5Z+nktfnT/AuzrtwzMnHXc/2oaPr8LmNai29C193SL3tulMBeVPXzhkRQJs/cjTg==" }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "sourcemap-codec": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz", + "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==" } } } diff --git a/packages/modules/package.js b/packages/modules/package.js index f8e3202d21..4b08c1452b 100644 --- a/packages/modules/package.js +++ b/packages/modules/package.js @@ -1,12 +1,12 @@ Package.describe({ name: "modules", - version: "0.14.0-beta182.10", + version: "0.14.0-beta182.11", summary: "CommonJS module system", documentation: "README.md" }); Npm.depends({ - reify: "0.20.6", + reify: "0.20.10", "meteor-babel-helpers": "0.0.3" }); diff --git a/packages/mongo/package.js b/packages/mongo/package.js index af28b41dce..b7c5534949 100644 --- a/packages/mongo/package.js +++ b/packages/mongo/package.js @@ -9,7 +9,7 @@ Package.describe({ summary: "Adaptor for using MongoDB and Minimongo over DDP", - version: '1.7.0-beta182.10' + version: '1.7.0-beta182.11' }); Npm.depends({ diff --git a/packages/npm-mongo/package.js b/packages/npm-mongo/package.js index a0a5c50439..dde50584f4 100644 --- a/packages/npm-mongo/package.js +++ b/packages/npm-mongo/package.js @@ -3,7 +3,7 @@ Package.describe({ summary: "Wrapper around the mongo npm package", - version: "3.2.0-beta182.10", + version: "3.2.0-beta182.11", documentation: null }); diff --git a/scripts/admin/meteor-release-experimental.json b/scripts/admin/meteor-release-experimental.json index 213a8eb666..7fa04af435 100644 --- a/scripts/admin/meteor-release-experimental.json +++ b/scripts/admin/meteor-release-experimental.json @@ -1,6 +1,6 @@ { "track": "METEOR", - "version": "1.8.2-beta.10", + "version": "1.8.2-beta.11", "recommended": false, "official": false, "description": "Meteor" diff --git a/scripts/dev-bundle-server-package.js b/scripts/dev-bundle-server-package.js index ec6a2bbed3..f4a97c98f9 100644 --- a/scripts/dev-bundle-server-package.js +++ b/scripts/dev-bundle-server-package.js @@ -13,7 +13,7 @@ var packageJson = { fibers: "3.1.1", "meteor-promise": "0.8.7", promise: "8.0.2", - reify: "0.18.1", + reify: "0.20.10", // Not yet upgrading Underscore from 1.5.2 to 1.7.0 (which should be done // in the package too) because we should consider using lodash instead // (and there are backwards-incompatible changes either way). diff --git a/scripts/dev-bundle-tool-package.js b/scripts/dev-bundle-tool-package.js index 6386088510..35b5bf07c2 100644 --- a/scripts/dev-bundle-tool-package.js +++ b/scripts/dev-bundle-tool-package.js @@ -14,11 +14,11 @@ var packageJson = { pacote: "https://github.com/meteor/pacote/tarball/c5043daa1b768594e01d76275e3854fc19f038f9", "node-gyp": "5.0.1", "node-pre-gyp": "0.13.0", - "meteor-babel": "7.4.15", + "meteor-babel": "7.4.18", // Keep the versions of these packages consistent with the versions // found in dev-bundle-server-package.js. "meteor-promise": "0.8.7", - reify: "0.20.6", + reify: "0.20.10", fibers: "3.1.1", // So that Babel can emit require("@babel/runtime/helpers/...") calls. "@babel/runtime": "7.4.4", diff --git a/tools/isobuild/compiler-plugin.js b/tools/isobuild/compiler-plugin.js index be9f762546..c65c191cd9 100644 --- a/tools/isobuild/compiler-plugin.js +++ b/tools/isobuild/compiler-plugin.js @@ -1343,7 +1343,6 @@ export class PackageSourceBatch { sourceRoot: batch.sourceRoot, nodeModulesPaths, watchSet: batch.unibuild.watchSet, - compileOneJsResource: batch.compileOneJsResource.bind(batch), cacheDir: batch.scannerCacheDir, }); diff --git a/tools/isobuild/import-scanner.js b/tools/isobuild/import-scanner.js index 248b62dbac..f0252dd05d 100644 --- a/tools/isobuild/import-scanner.js +++ b/tools/isobuild/import-scanner.js @@ -36,7 +36,6 @@ const { import { optimisticReadFile, optimisticStatOrNull, - optimisticLookupPackageJson, optimisticLStatOrNull, optimisticHashOrNull, shouldWatch, @@ -65,26 +64,36 @@ function stripHashBang(dataString) { return dataString.replace(/^#![^\n]*/, ""); } -const reifyCompileWithCache = wrap(function ({ dataString }) { - return reifyCompile(stripHashBang(dataString), { +const reifyCompileWithCache = Profile("reifyCompileWithCache", wrap(function ( + source, + hash, + bundleArch, +) { + const isLegacy = + bundleArch === "web.browser.legacy" || + bundleArch === "web.cordova"; + + return reifyCompile(stripHashBang(source), { + generateLetDeclarations: !isLegacy, + avoidModernSyntax: isLegacy, + enforceStrictMode: false, dynamicImport: true, + ast: false, }).code; }, { - makeCacheKey({ hash }) { - return hash; + makeCacheKey(source, hash, bundleArch) { + return JSON.stringify([hash, bundleArch]); } -}); +})); class DefaultHandlers { constructor({ sourceRoot, cacheDir, bundleArch, - compileOneJsResource, }) { Object.assign(this, { sourceRoot, - compileOneJsResource, }); if (cacheDir) { @@ -100,14 +109,16 @@ class DefaultHandlers { } js(file) { - if (this.compileOneJsResource) { - const jsOutputResources = this.compileOneJsResource({ - data: file.data, - path: pathRelative(this.sourceRoot, file.absPath), - hash: file.hash, - }); - if (jsOutputResources.length > 0) { - return jsOutputResources[0].data.toString("utf8"); + const parts = file.absPath.split("/"); + const nmi = parts.lastIndexOf("node_modules"); + if (nmi >= 0) { + const nextPart = parts[nmi + 1]; + // The core-js package is one example of a package that does not + // need recompilation to support import/export syntax. Since it is + // used heavily by the ecmascript-runtime-{client,server} Meteor + // packages, it makes sense to hard-code this exception. + if (nextPart === "core-js") { + return stripHashBang(file.dataString); } } @@ -117,12 +128,20 @@ class DefaultHandlers { return optimisticReadFile(cacheFileName, "utf8"); } catch (e) { if (e.code !== "ENOENT") throw e; - const code = reifyCompileWithCache(file); + const code = reifyCompileWithCache( + file.dataString, + file.hash, + this.bundleArch, + ); process.nextTick(writeFileAtomically, cacheFileName, code); return code; } } else { - return reifyCompileWithCache(file); + return reifyCompileWithCache( + file.dataString, + file.hash, + this.bundleArch, + ); } } @@ -255,7 +274,6 @@ export default class ImportScanner { nodeModulesPaths = [], watchSet, cacheDir, - compileOneJsResource, }) { assert.ok(isString(sourceRoot)); @@ -275,7 +293,6 @@ export default class ImportScanner { sourceRoot, cacheDir, bundleArch, - compileOneJsResource, }); this.resolver = Resolver.getOrCreate({ @@ -1150,15 +1167,7 @@ export default class ImportScanner { // raw version found in node_modules. See also: // https://github.com/meteor/meteor-feature-requests/issues/6 - } else if ( - this._shouldUseNode(absModuleId) && - // If the package has a "module" entry point in its package.json file, - // there's a chance someone might import an ESM module from the package - // on the server (without going through package.json), so to be safe we - // need to compile ESM syntax for any modules imported from the package, - // instead of just calling module.useNode() and hoping for the best. - ! this._hasModuleEntryPoint(absPath) - ) { + } else if (this._shouldUseNode(absModuleId)) { // On the server, modules in node_modules directories will be // handled natively by Node, so we just need to generate a stub // module that calls module.useNode(), rather than calling @@ -1205,34 +1214,6 @@ export default class ImportScanner { return depFile; } - _hasModuleEntryPoint(absPath) { - const pkgJson = this._lookupPackageJson(absPath); - // Similar to logic in PackageSource#_findSources. - return pkgJson && ( - typeof pkgJson.module === "string" || - pkgJson.type === "module" - ); - } - - _lookupPackageJson(absPath) { - const relDir = pathRelative( - this.sourceRoot, - pathDirname(absPath), - ); - - if (relDir.startsWith("..")) { - const absParts = absPath.split("/"); - absParts.pop(); // Get rid of base filename. - const nmi = absParts.lastIndexOf("node_modules"); - return optimisticLookupPackageJson( - absParts.slice(0, nmi + 1).join("/"), - absParts.slice(nmi + 1).join("/"), - ); - } - - return optimisticLookupPackageJson(this.sourceRoot, relDir); - } - // Similar to logic in Module.prototype.useNode as defined in // packages/modules-runtime/server.js. Introduced to fix issue #10122. _shouldUseNode(absModuleId) { diff --git a/tools/isobuild/package-source.js b/tools/isobuild/package-source.js index 210f6d03e8..ec0998d9fc 100644 --- a/tools/isobuild/package-source.js +++ b/tools/isobuild/package-source.js @@ -860,6 +860,9 @@ _.extend(PackageSource.prototype, { const testModulesByArch = projectContext.meteorConfig.getTestModulesByArch(); + const nodeModulesToRecompileByArch = + projectContext.meteorConfig.getNodeModulesToRecompileByArch(); + projectWatchSet.merge(projectContext.meteorConfig.watchSet); _.each(compiler.ALL_ARCHES, function (arch) { @@ -871,10 +874,13 @@ _.extend(PackageSource.prototype, { } const mainModule = projectContext.meteorConfig - .getMainModuleForArch(arch, mainModulesByArch); + .getMainModule(arch, mainModulesByArch); const testModule = projectContext.meteorConfig - .getTestModuleForArch(arch, testModulesByArch); + .getTestModule(arch, testModulesByArch); + + const nodeModulesToRecompile = projectContext.meteorConfig + .getNodeModulesToRecompile(arch, nodeModulesToRecompileByArch); // XXX what about /web.browser/* etc, these directories could also // be for specific client targets. @@ -895,6 +901,7 @@ _.extend(PackageSource.prototype, { ignoreFiles, isApp: true, testModule, + nodeModulesToRecompile, }; // If this architecture has a mainModule defined in @@ -1094,6 +1101,7 @@ _.extend(PackageSource.prototype, { isApp, sourceArch, testModule, + nodeModulesToRecompile = new Set, loopChecker = new SymlinkLoopChecker(this.sourceRoot), ignoreFiles = [] }) { @@ -1254,7 +1262,7 @@ _.extend(PackageSource.prototype, { // If we're in a node_modules directory, cache the results of the // find function for the duration of the process. - const cacheKey = inNodeModules && makeCacheKey(dir); + let cacheKey = inNodeModules && makeCacheKey(dir); if (cacheKey && cacheKey in self._findSourcesCache) { return self._findSourcesCache[cacheKey]; @@ -1273,14 +1281,22 @@ _.extend(PackageSource.prototype, { } } - const pkgJson = optimisticLookupPackageJson(self.sourceRoot, dir); - const hasModuleEntryPoint = pkgJson && ( - isWeb ? typeof pkgJson.module === "string" : pkgJson.type === "module" - ); + let readOptions = sourceReadOptions; + if (inNodeModules) { + const pkgJson = optimisticLookupPackageJson(self.sourceRoot, dir); + const shouldRecompile = + pkgJson && nodeModulesToRecompile.has(pkgJson.name); + const hasModuleEntryPoint = pkgJson && ( + typeof pkgJson.module === "string" || pkgJson.type === "module" + ); - const readOptions = inNodeModules && !hasModuleEntryPoint - ? nodeModulesReadOptions - : sourceReadOptions; + if (hasModuleEntryPoint || shouldRecompile) { + // Avoid caching node_modules code recompiled by Meteor. + cacheKey = false; + } else { + readOptions = nodeModulesReadOptions; + } + } const sources = _.difference( self._readAndWatchDirectory(dir, watchSet, readOptions), diff --git a/tools/project-context.js b/tools/project-context.js index 7806436baf..fdc136b9f2 100644 --- a/tools/project-context.js +++ b/tools/project-context.js @@ -1649,9 +1649,47 @@ export class MeteorConfig { } } - // Call this first if you plan to call getMainModuleForArch multiple + getNodeModulesToRecompileByArch() { + const packageNamesByArch = Object.create(null); + const recompile = this.get("nodeModules", "recompile"); + + if (recompile && typeof recompile === "object") { + const get = arch => packageNamesByArch[arch] || ( + packageNamesByArch[arch] = new Set); + + Object.keys(recompile).forEach(packageName => { + const info = recompile[packageName]; + if (! info) return; + if (info === true) { + get("web").add(packageName); + get("os").add(packageName); + } else if (typeof info === "string") { + mapWhereToArches(info).forEach(arch => { + get(arch).add(packageName); + }); + } else if (Array.isArray(info)) { + info.forEach(where => { + mapWhereToArches(where).forEach(arch => { + get(arch).add(packageName); + }); + }); + } + }); + } + + return packageNamesByArch; + } + + getNodeModulesToRecompile( + arch, + packageNamesByArch = this.getNodeModulesToRecompileByArch(), + ) { + return packageNamesByArch[arch]; + } + + // Call this first if you plan to call getMainModule multiple // times, so that you can avoid repeating this work each time. - getMainModulesByArch(arch) { + getMainModulesByArch() { return this._getEntryModulesByArch("mainModule"); } @@ -1659,24 +1697,24 @@ export class MeteorConfig { // that architecture. For example, if this.config.mainModule.client is // defined, then because mapWhereToArch("client") === "web", and "web" // matches web.browser, return this.config.mainModule.client. - getMainModuleForArch( + getMainModule( arch, mainModulesByArch = this.getMainModulesByArch(), ) { - return this._getEntryModuleForArch(arch, mainModulesByArch); + return this._getEntryModule(arch, mainModulesByArch); } // Analogous to getMainModulesByArch, except for this.config.testModule. - getTestModulesByArch(arch) { + getTestModulesByArch() { return this._getEntryModulesByArch("testModule"); } - // Analogous to getMainModuleForArch, except for this.config.testModule. - getTestModuleForArch( + // Analogous to getMainModule, except for this.config.testModule. + getTestModule( arch, testModulesByArch = this.getTestModulesByArch(), ) { - return this._getEntryModuleForArch(arch, testModulesByArch); + return this._getEntryModule(arch, testModulesByArch); } _getEntryModulesByArch(...keys) { @@ -1703,7 +1741,7 @@ export class MeteorConfig { return entryModulesByArch; } - _getEntryModuleForArch( + _getEntryModule( arch, entryModulesByArch, ) { diff --git a/tools/static-assets/server/runtime.js b/tools/static-assets/server/runtime.js index 7faf43f6e6..f824dceb8c 100644 --- a/tools/static-assets/server/runtime.js +++ b/tools/static-assets/server/runtime.js @@ -23,3 +23,18 @@ const resolved = Promise.resolve(); Mp.dynamicImport = function (id) { return resolved.then(() => require(id)); }; + +const parse = require("reify/lib/parsers/default").parse; +const reifyCompile = require("reify/lib/compiler").compile; +const _compile = Mp._compile; +Mp._compile = function (content, filename) { + const result = reifyCompile(content, { + parse: parse, + generateLetDeclarations: false, + ast: false, + }); + if (!result.identical) { + content = result.code; + } + return _compile.call(this, content, filename); +}; diff --git a/tools/tests/apps/modules/package-lock.json b/tools/tests/apps/modules/package-lock.json index e4166432ad..a45d1462c4 100644 --- a/tools/tests/apps/modules/package-lock.json +++ b/tools/tests/apps/modules/package-lock.json @@ -12,17 +12,17 @@ } }, "@babel/core": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.3.tgz", - "integrity": "sha512-oDpASqKFlbspQfzAE7yaeTmdljSH2ADIvBlb0RwbStltTuWa0+7CCI1fYVINNv9saHPa1W7oaKeuNuKj+RQCvA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", + "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", - "@babel/helpers": "^7.4.3", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", + "@babel/generator": "^7.4.4", + "@babel/helpers": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.5", + "@babel/types": "^7.4.4", "convert-source-map": "^1.1.0", "debug": "^4.1.0", "json5": "^2.1.0", @@ -33,11 +33,11 @@ } }, "@babel/generator": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", - "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "requires": { - "@babel/types": "^7.4.0", + "@babel/types": "^7.4.4", "jsesc": "^2.5.1", "lodash": "^4.17.11", "source-map": "^0.5.0", @@ -68,21 +68,21 @@ "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" }, "@babel/helper-split-export-declaration": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", - "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "requires": { - "@babel/types": "^7.4.0" + "@babel/types": "^7.4.4" } }, "@babel/helpers": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.3.tgz", - "integrity": "sha512-BMh7X0oZqb36CfyhvtbSmcWc3GXocfxv3yNsAEuM0l+fAqSO22rQrUpijr3oE/10jCTrB6/0b9kzmG4VetCj8Q==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", "requires": { - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0" + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/highlight": { @@ -96,9 +96,9 @@ } }, "@babel/parser": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.3.tgz", - "integrity": "sha512-gxpEUhTS1sGA63EGQGuA+WESPR/6tz6ng7tSHFCmaTJK/cGK8y37cBTspX+U2xCAue2IQVvF6Z0oigmjwD8YGQ==" + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==" }, "@babel/plugin-proposal-do-expressions": { "version": "7.2.0", @@ -135,9 +135,9 @@ } }, "@babel/runtime": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.3.tgz", - "integrity": "sha512-9lsJwJLxDh/T3Q3SZszfWOTkk3pHbkmH+3KY+zwIDmsNlxsumuhS2TH3NIpktU4kNvfzy+k3eLT7aTJSPTo0OA==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz", + "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==", "requires": { "regenerator-runtime": "^0.13.2" }, @@ -150,41 +150,49 @@ } }, "@babel/template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", - "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0" + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" } }, "@babel/traverse": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.3.tgz", - "integrity": "sha512-HmA01qrtaCwwJWpSKpA948cBvU5BrmviAief/b3AVw936DtcdsTexlbyzNuDnthwhOQ37xshn7hvQaEQk7ISYQ==", + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", "requires": { "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", + "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/types": "^7.4.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.11" } }, "@babel/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", - "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" } }, + "@polymer/lit-element": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@polymer/lit-element/-/lit-element-0.7.1.tgz", + "integrity": "sha512-aYSzVhC19l7xSm73aHI06VPcD/H+GxpFNZrhbJ+zVIpgAveOgGp5Ga7UtTBHQCdHlJbZ0dMlaBXMZ3twgXCokg==", + "requires": { + "lit-html": "^1.0.0-rc.2" + } + }, "@wry/context": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.4.0.tgz", @@ -527,9 +535,9 @@ } }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==" + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "graphql": { "version": "14.3.1", @@ -658,6 +666,11 @@ "react": "16.4.1" } }, + "lit-html": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-1.1.0.tgz", + "integrity": "sha512-ZDJHpJi09yknMpjwPI8fuSl5sUG7+pF+eE5WciFtgyX7zebvgMDBgSLq4knXa7grxM00RkQ7PBd7UZQiruA78Q==" + }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", @@ -1474,9 +1487,9 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "requires": { "path-parse": "^1.0.6" } diff --git a/tools/tests/apps/modules/package.json b/tools/tests/apps/modules/package.json index 84de7c8e05..29e6a6fca4 100644 --- a/tools/tests/apps/modules/package.json +++ b/tools/tests/apps/modules/package.json @@ -4,10 +4,11 @@ "description": "Test app exercising many aspects of the Meteor module system.", "private": true, "dependencies": { - "@babel/core": "^7.0.0-beta.56", - "@babel/plugin-proposal-do-expressions": "^7.0.0-beta.56", - "@babel/plugin-proposal-optional-chaining": "^7.0.0-beta.56", - "@babel/runtime": "^7.1.2", + "@babel/core": "^7.4.5", + "@babel/plugin-proposal-do-expressions": "^7.2.0", + "@babel/plugin-proposal-optional-chaining": "^7.2.0", + "@babel/runtime": "^7.4.5", + "@polymer/lit-element": "0.7.1", "@wry/context": "^0.4.0", "acorn": "file:imports/links/acorn", "aws-sdk": "^2.2.41", @@ -36,6 +37,12 @@ "test-packages": "TEST_BROWSER_DRIVER=puppeteer meteor test-packages --driver-package meteortesting:mocha packages/modules-test-package" }, "meteor": { - "testModule": "tests.js" + "testModule": "tests.js", + "nodeModules": { + "recompile": { + "pify": "legacy", + "@polymer/lit-element": true + } + } } } diff --git a/tools/tests/apps/modules/tests.js b/tools/tests/apps/modules/tests.js index 182866b2a2..9d04147f3e 100644 --- a/tools/tests/apps/modules/tests.js +++ b/tools/tests/apps/modules/tests.js @@ -371,6 +371,47 @@ describe("local node_modules", () => { assert.strictEqual(typeof parse, "function"); assert.strictEqual(parse, nestedParse); }); + + Meteor.isClient && it("can import @polymer/lit-element", () => { + // This import is enabled by the meteor.nodeModules.recompile section of + // the package.json file for the modules test application. + const litElement = require("@polymer/lit-element"); + const typeofMap = {}; + Object.keys(litElement).forEach(key => { + typeofMap[key] = typeof litElement[key]; + }); + + assert.deepEqual(typeofMap, { + defaultConverter: "object", + notEqual: "function", + UpdatingElement: "function", + customElement: "function", + property: "function", + query: "function", + queryAll: "function", + eventOptions: "function", + html: "function", + svg: "function", + TemplateResult: "function", + SVGTemplateResult: "function", + supportsAdoptingStyleSheets: "boolean", + CSSResult: "function", + css: "function", + LitElement: "function" + }); + }); + + it("can import @babel/runtime/helpers/esm/*", () => { + function check(exports) { + assert.strictEqual(typeof exports.default, "function"); + } + check(require("@babel/runtime/helpers/esm/asyncIterator.js")); + check(require("@babel/runtime/helpers/esm/createClass.js")); + check(require("@babel/runtime/helpers/esm/getPrototypeOf.js")); + check(require("@babel/runtime/helpers/esm/inherits.js")); + check(require("@babel/runtime/helpers/esm/toArray.js")); + check(require("@babel/runtime/helpers/esm/typeof.js")); + }); }); describe("Meteor packages", () => {