From f16a04fffd71413a64a575c39621c59964c0a4a3 Mon Sep 17 00:00:00 2001 From: Sourav Shaw Date: Fri, 6 Aug 2021 12:38:19 +0530 Subject: [PATCH 01/42] fixes #6658 (assertion error in BundleAnalyzer) (#6674) --- .../reporters/bundle-analyzer/src/BundleAnalyzerReporter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js b/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js index a4343069b36..746f51c14fb 100644 --- a/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js +++ b/packages/reporters/bundle-analyzer/src/BundleAnalyzerReporter.js @@ -126,7 +126,7 @@ async function getBundleNode(bundle: PackagedBundle, options: PluginOptions) { let relativePath = path.relative(options.projectRoot, asset.filePath); let parts = relativePath.split(path.sep); let dirs = parts.slice(0, parts.length - 1); - let basename = parts[parts.length - 1]; + let basename = path.basename(asset.filePath); let map = dirMap; for (let dir of dirs) { @@ -136,7 +136,7 @@ async function getBundleNode(bundle: PackagedBundle, options: PluginOptions) { invariant(map instanceof DefaultMap); map.set(basename, { - basename: path.basename(asset.filePath), + basename, size: asset.size, }); } From 4df85e34d919f75cfa0d8ad79e9cc7d4fd19f716 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Fri, 6 Aug 2021 17:57:24 +0100 Subject: [PATCH 02/42] Add type for WorkerFarm.end() (#6690) --- packages/core/workers/index.d.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core/workers/index.d.ts b/packages/core/workers/index.d.ts index b91f889119a..f081fa34285 100644 --- a/packages/core/workers/index.d.ts +++ b/packages/core/workers/index.d.ts @@ -15,6 +15,8 @@ export type FarmOptions = { declare class WorkerFarm { constructor(options: FarmOptions); + + end(): Promise; } export default WorkerFarm; From 2e58db8a949ffecfc53115fcd53b514ceb9a1d4c Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Tue, 10 Aug 2021 14:51:50 -0700 Subject: [PATCH 03/42] Don't include the default export in static reexports (#6701) --- .../es6/no-reexport-default/a.js | 5 +++++ .../es6/no-reexport-default/async.js | 5 +++++ .../es6/no-reexport-default/b.js | 1 + .../es6/no-reexport-default/c.js | 1 + .../es6/no-reexport-default/index.js | 3 +++ .../es6/no-reexport-esmodule/a.js | 2 ++ .../es6/no-reexport-esmodule/async.js | 1 + .../es6/no-reexport-esmodule/index.js | 3 +++ .../integration-tests/test/scope-hoisting.js | 22 +++++++++++++++++++ .../packagers/js/src/ScopeHoistingPackager.js | 7 ++++++ 10 files changed, 50 insertions(+) create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/a.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/async.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/b.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/c.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/index.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/a.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/async.js create mode 100644 packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/index.js diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/a.js new file mode 100644 index 00000000000..f4ef1a62f0c --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/a.js @@ -0,0 +1,5 @@ +export {default} from './b.js'; +export * from './b.js'; + +export {default as other} from './c.js'; +export * from './c.js'; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/async.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/async.js new file mode 100644 index 00000000000..effda9f6898 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/async.js @@ -0,0 +1,5 @@ +import _default, {other} from './a.js'; + +sideEffectNoop(_default, other); + +export default _default; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/b.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/b.js new file mode 100644 index 00000000000..7a4e8a723a4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/b.js @@ -0,0 +1 @@ +export default 42; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/c.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/c.js new file mode 100644 index 00000000000..4a45ec62226 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/c.js @@ -0,0 +1 @@ +export default 99; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/index.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/index.js new file mode 100644 index 00000000000..4d154549b02 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-default/index.js @@ -0,0 +1,3 @@ +import _default, {other} from './a.js'; + +output = import('./async').then(mod => mod.default); diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/a.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/a.js new file mode 100644 index 00000000000..001aee69b47 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/a.js @@ -0,0 +1,2 @@ +module.exports.foo = 42; +module.exports.__esModule = true; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/async.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/async.js new file mode 100644 index 00000000000..69f6e6a7942 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/async.js @@ -0,0 +1 @@ +export * from './a'; diff --git a/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/index.js b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/index.js new file mode 100644 index 00000000000..7b266d0d780 --- /dev/null +++ b/packages/core/integration-tests/test/integration/scope-hoisting/es6/no-reexport-esmodule/index.js @@ -0,0 +1,3 @@ +import * as a from './a.js'; + +output = import('./async').then(mod => mod.__esModule); diff --git a/packages/core/integration-tests/test/scope-hoisting.js b/packages/core/integration-tests/test/scope-hoisting.js index 0118744826c..39c215b3ae4 100644 --- a/packages/core/integration-tests/test/scope-hoisting.js +++ b/packages/core/integration-tests/test/scope-hoisting.js @@ -3714,6 +3714,28 @@ describe('scope hoisting', function() { let test = await run(b); assert.equal(test({foo: 2}), 2); }); + + it('should not include default when reexporting * without $parcel$exportWildcard', async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/scope-hoisting/es6/no-reexport-default/index.js', + ), + ); + + assert.equal(await run(b), 42); + }); + + it('should not include __esModule when reexporting * without $parcel$exportWildcard', async () => { + let b = await bundle( + path.join( + __dirname, + 'integration/scope-hoisting/es6/no-reexport-esmodule/index.js', + ), + ); + + assert.equal(await run(b), undefined); + }); }); describe('commonjs', function() { diff --git a/packages/packagers/js/src/ScopeHoistingPackager.js b/packages/packagers/js/src/ScopeHoistingPackager.js index af3329ebff0..2514347b5c5 100644 --- a/packages/packagers/js/src/ScopeHoistingPackager.js +++ b/packages/packagers/js/src/ScopeHoistingPackager.js @@ -983,6 +983,13 @@ ${code} this.usedHelpers.add('$parcel$exportWildcard'); } else { for (let symbol of this.bundleGraph.getUsedSymbols(dep)) { + if ( + symbol === 'default' || // `export * as ...` does not include the default export + symbol === '__esModule' + ) { + continue; + } + let resolvedSymbol = this.getSymbolResolution( asset, resolved, From 7c4d267ee0b61c12f57c95db9e5d24860e386680 Mon Sep 17 00:00:00 2001 From: Burak Karakan Date: Wed, 11 Aug 2021 17:38:18 +0100 Subject: [PATCH 04/42] Upgrade the ejs version for the dev-server reporter (#6678) --- packages/reporters/dev-server/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/reporters/dev-server/package.json b/packages/reporters/dev-server/package.json index 806bfdcaf82..f94416581f8 100644 --- a/packages/reporters/dev-server/package.json +++ b/packages/reporters/dev-server/package.json @@ -24,7 +24,7 @@ "@parcel/plugin": "2.0.0-rc.0", "@parcel/utils": "2.0.0-rc.0", "connect": "^3.7.0", - "ejs": "^2.6.1", + "ejs": "^3.1.6", "http-proxy-middleware": "^1.0.0", "nullthrows": "^1.1.1", "serve-handler": "^6.0.0", From f9887fef5f1adc85cf3569a2081987c0db4036c8 Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Thu, 12 Aug 2021 06:14:04 +0100 Subject: [PATCH 05/42] Export core class in TypeScript (#6686) --- packages/core/core/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/core/index.d.ts b/packages/core/core/index.d.ts index b900d395030..5da6802752e 100644 --- a/packages/core/core/index.d.ts +++ b/packages/core/core/index.d.ts @@ -2,7 +2,7 @@ import type {InitialParcelOptions, BuildEvent, BuildSuccessEvent, AsyncSubscript import type {FarmOptions} from '@parcel/workers'; import type WorkerFarm from '@parcel/workers'; -declare class Parcel { +export default class Parcel { constructor(options: InitialParcelOptions); run(): Promise; watch( From aa21e8990fb6a95a0df8ce6cdf1ebada2342230a Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 15 Aug 2021 18:52:13 -0700 Subject: [PATCH 06/42] Resolver improvements (#6696) --- .../core/src/requests/ParcelConfigRequest.js | 16 +- .../core/core/src/requests/PathRequest.js | 91 +--- packages/core/core/test/ParcelConfig.test.js | 3 +- packages/core/integration-tests/test/css.js | 37 ++ .../parcel-transformer-mock/index.js | 3 +- .../test/integration/css-external/a.css | 6 + .../test/integration/css-external/b.css | 3 + .../integration/css-node-modules/index.css | 1 + .../css-node-modules/node_modules/foo/foo.css | 3 + .../node_modules/foo/package.json | 3 + .../test/integration/image/reformat.js | 4 +- .../parcel-resolver-no-defer/index.js | 6 +- .../test/integration/swc-helpers/yarn.lock | 0 .../core/integration-tests/test/javascript.js | 6 +- .../integration-tests/test/transpilation.js | 2 +- packages/core/types/index.js | 13 +- packages/core/utils/src/alternatives.js | 9 +- packages/packagers/css/src/CSSPackager.js | 24 +- .../resolvers/default/src/DefaultResolver.js | 13 +- packages/resolvers/glob/src/GlobResolver.js | 14 +- .../transformers/css/src/CSSTransformer.js | 58 ++- .../node-resolver-core/src/NodeResolver.js | 160 +++++-- .../utils/node-resolver-core/test/resolver.js | 396 +++++++++++++++--- 23 files changed, 639 insertions(+), 232 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/css-external/a.css create mode 100644 packages/core/integration-tests/test/integration/css-external/b.css create mode 100644 packages/core/integration-tests/test/integration/css-node-modules/index.css create mode 100644 packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/foo.css create mode 100644 packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/package.json create mode 100644 packages/core/integration-tests/test/integration/swc-helpers/yarn.lock diff --git a/packages/core/core/src/requests/ParcelConfigRequest.js b/packages/core/core/src/requests/ParcelConfigRequest.js index b2562c93855..463a984dfc5 100644 --- a/packages/core/core/src/requests/ParcelConfigRequest.js +++ b/packages/core/core/src/requests/ParcelConfigRequest.js @@ -264,6 +264,16 @@ function processPipeline( } } +const RESERVED_PIPELINES = new Set([ + 'node:', + 'npm:', + 'http:', + 'https:', + 'data:', + 'tel:', + 'mailto:', +]); + async function processMap( // $FlowFixMe map: ?ConfigMap, @@ -277,12 +287,12 @@ async function processMap( // $FlowFixMe let res: ConfigMap = {}; for (let k in map) { - if (k.startsWith('node:')) { + let i = k.indexOf(':'); + if (i > 0 && RESERVED_PIPELINES.has(k.slice(0, i + 1))) { let code = await options.inputFS.readFile(filePath, 'utf8'); throw new ThrowableDiagnostic({ diagnostic: { - message: - 'Named pipeline `node:` is reserved for builtin Node.js libraries', + message: `Named pipeline '${k.slice(0, i + 1)}' is reserved.`, origin: '@parcel/core', codeFrames: [ { diff --git a/packages/core/core/src/requests/PathRequest.js b/packages/core/core/src/requests/PathRequest.js index ada5fb8dddf..73bdcd62c93 100644 --- a/packages/core/core/src/requests/PathRequest.js +++ b/packages/core/core/src/requests/PathRequest.js @@ -1,11 +1,6 @@ // @flow strict-local import type {Diagnostic} from '@parcel/diagnostic'; -import type { - Async, - FileCreateInvalidation, - FilePath, - QueryParameters, -} from '@parcel/types'; +import type {Async, FileCreateInvalidation, FilePath} from '@parcel/types'; import type {StaticRunOpts} from '../RequestTracker'; import type {AssetGroup, Dependency, ParcelOptions} from '../types'; import type {ConfigAndCachePath} from './ParcelConfigRequest'; @@ -14,9 +9,7 @@ import ThrowableDiagnostic, {errorToDiagnostic, md} from '@parcel/diagnostic'; import {PluginLogger} from '@parcel/logger'; import nullthrows from 'nullthrows'; import path from 'path'; -import URL from 'url'; import {normalizePath} from '@parcel/utils'; -import querystring from 'querystring'; import {report} from '../ReporterRunner'; import PublicDependency from '../public/Dependency'; import PluginOptions from '../public/PluginOptions'; @@ -50,7 +43,6 @@ type RunOpts = {| |}; const type = 'path_request'; -const QUERY_PARAMS_REGEX = /^([^\t\r\n\v\f?]*)(\?.*)?/; const PIPELINE_REGEX = /^([a-z0-9-]+?):(.*)$/i; export default function createPathRequest( @@ -166,8 +158,7 @@ export class ResolverRunner { let resolvers = await this.config.getResolvers(); let pipeline; - let filePath; - let query: ?QueryParameters; + let specifier; let validPipelines = new Set(this.config.getNamedPipelines()); let match = dependency.specifier.match(PIPELINE_REGEX); if ( @@ -176,74 +167,20 @@ export class ResolverRunner { // and include e.g. `C:\` on Windows, conflicting with pipelines. !path.isAbsolute(dependency.specifier) ) { - if (dependency.specifier.startsWith('node:')) { - filePath = dependency.specifier; - } else { - [, pipeline, filePath] = match; - if (!validPipelines.has(pipeline)) { - if (dep.specifierType === 'url') { - // This may be a url protocol or scheme rather than a pipeline, such as - // `url('http://example.com/foo.png')` - return {assetGroup: null}; - } else { - return { - assetGroup: null, - diagnostics: [ - await this.getDiagnostic( - dependency, - md`Unknown pipeline: ${pipeline}.`, - ), - ], - }; - } - } - } - } else { - if (dep.specifierType === 'url') { - if (dependency.specifier.startsWith('//')) { - // A protocol-relative URL, e.g `url('//example.com/foo.png')` - return {assetGroup: null}; - } - if (dependency.specifier.startsWith('#')) { - // An ID-only URL, e.g. `url(#clip-path)` for CSS rules - return {assetGroup: null}; - } - } - filePath = dependency.specifier; - } - - let queryPart = null; - if (dep.specifierType === 'url') { - let parsed = URL.parse(filePath); - if (typeof parsed.pathname !== 'string') { - return { - assetGroup: null, - diagnostics: [ - await this.getDiagnostic( - dependency, - md`Received URL without a pathname ${filePath}.`, - ), - ], - }; - } - filePath = decodeURIComponent(parsed.pathname); - if (parsed.query != null) { - queryPart = parsed.query; + [, pipeline, specifier] = match; + if (!validPipelines.has(pipeline)) { + // This may be a url protocol or scheme rather than a pipeline, such as + // `url('http://example.com/foo.png')`. Pass it to resolvers to handle. + specifier = dependency.specifier; + pipeline = null; } } else { - let matchesQuerystring = filePath.match(QUERY_PARAMS_REGEX); - if (matchesQuerystring && matchesQuerystring[2] != null) { - filePath = matchesQuerystring[1]; - queryPart = matchesQuerystring[2].substr(1); - } - } - if (queryPart != null) { - query = querystring.parse(queryPart); + specifier = dependency.specifier; } // Entrypoints, convert ProjectPath in module specifier to absolute path if (dep.resolveFrom == null) { - filePath = path.join(this.options.projectRoot, filePath); + specifier = path.join(this.options.projectRoot, specifier); } let diagnostics: Array = []; let invalidateOnFileCreate = []; @@ -251,7 +188,7 @@ export class ResolverRunner { for (let resolver of resolvers) { try { let result = await resolver.plugin.resolve({ - filePath, + specifier, pipeline, dependency: dep, options: this.pluginOptions, @@ -302,7 +239,7 @@ export class ResolverRunner { this.options.projectRoot, resultFilePath, ), - query, + query: result.query, sideEffects: result.sideEffects, code: result.code, env: dependency.env, @@ -322,7 +259,7 @@ export class ResolverRunner { new ThrowableDiagnostic({diagnostic: result.diagnostics}), { origin: resolver.name, - filePath, + filePath: specifier, }, ); diagnostics.push(...errorDiagnostic); @@ -332,7 +269,7 @@ export class ResolverRunner { // Add error to error map, we'll append these to the standard error if we can't resolve the asset let errorDiagnostic = errorToDiagnostic(e, { origin: resolver.name, - filePath, + filePath: specifier, }); if (Array.isArray(errorDiagnostic)) { diagnostics.push(...errorDiagnostic); diff --git a/packages/core/core/test/ParcelConfig.test.js b/packages/core/core/test/ParcelConfig.test.js index e58cfb8190a..4d1c23760d8 100644 --- a/packages/core/core/test/ParcelConfig.test.js +++ b/packages/core/core/test/ParcelConfig.test.js @@ -289,8 +289,7 @@ describe('ParcelConfig', () => { name: 'Error', diagnostics: [ { - message: - 'Named pipeline `node:` is reserved for builtin Node.js libraries', + message: "Named pipeline 'node:' is reserved.", origin: '@parcel/core', codeFrames: [ { diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index a9b46c6484f..766590d9439 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -381,4 +381,41 @@ describe('css', () => { }, ); }); + + it('should support importing CSS from node_modules with the npm: scheme', async () => { + let b = await bundle( + path.join(__dirname, '/integration/css-node-modules/index.css'), + ); + + assertBundles(b, [ + { + name: 'index.css', + assets: ['index.css', 'foo.css'], + }, + ]); + }); + + it('should support external CSS imports', async () => { + let b = await bundle( + path.join(__dirname, '/integration/css-external/a.css'), + ); + + assertBundles(b, [ + { + name: 'a.css', + assets: ['a.css', 'b.css'], + }, + ]); + + let res = await outputFS.readFile(b.getBundles()[0].filePath, 'utf8'); + assert( + res.startsWith(`@import "http://example.com/external.css"; +.b { + color: red; +} +.a { + color: blue; +}`), + ); + }); }); diff --git a/packages/core/integration-tests/test/integration/cache/node_modules/parcel-transformer-mock/index.js b/packages/core/integration-tests/test/integration/cache/node_modules/parcel-transformer-mock/index.js index 9aa8b706deb..476deaef29f 100644 --- a/packages/core/integration-tests/test/integration/cache/node_modules/parcel-transformer-mock/index.js +++ b/packages/core/integration-tests/test/integration/cache/node_modules/parcel-transformer-mock/index.js @@ -4,7 +4,8 @@ module.exports = new Transformer({ transform({asset}) { if (asset.isSource) { asset.addDependency({ - specifier: 'foo' + specifier: 'foo', + specifierType: 'esm' }); return [asset]; } diff --git a/packages/core/integration-tests/test/integration/css-external/a.css b/packages/core/integration-tests/test/integration/css-external/a.css new file mode 100644 index 00000000000..f3aff0a9f8d --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-external/a.css @@ -0,0 +1,6 @@ +@import 'b.css'; +@import 'http://example.com/external.css'; + +.a { + color: blue; +} diff --git a/packages/core/integration-tests/test/integration/css-external/b.css b/packages/core/integration-tests/test/integration/css-external/b.css new file mode 100644 index 00000000000..49533bc2338 --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-external/b.css @@ -0,0 +1,3 @@ +.b { + color: red; +} \ No newline at end of file diff --git a/packages/core/integration-tests/test/integration/css-node-modules/index.css b/packages/core/integration-tests/test/integration/css-node-modules/index.css new file mode 100644 index 00000000000..f59e597326c --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-node-modules/index.css @@ -0,0 +1 @@ +@import 'npm:foo/foo.css'; diff --git a/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/foo.css b/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/foo.css new file mode 100644 index 00000000000..dc1b2983f0b --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/foo.css @@ -0,0 +1,3 @@ +.foo { + background-color: red; +} \ No newline at end of file diff --git a/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/package.json b/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/package.json new file mode 100644 index 00000000000..bde99de9287 --- /dev/null +++ b/packages/core/integration-tests/test/integration/css-node-modules/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "name": "foo" +} diff --git a/packages/core/integration-tests/test/integration/image/reformat.js b/packages/core/integration-tests/test/integration/image/reformat.js index cd6ae6e6202..9302ce8284d 100755 --- a/packages/core/integration-tests/test/integration/image/reformat.js +++ b/packages/core/integration-tests/test/integration/image/reformat.js @@ -1 +1,3 @@ -module.exports = require('./image.jpg?as=webp'); +import url from './image.jpg?as=webp'; + +module.exports = url; diff --git a/packages/core/integration-tests/test/integration/resolver-canDefer/node_modules/parcel-resolver-no-defer/index.js b/packages/core/integration-tests/test/integration/resolver-canDefer/node_modules/parcel-resolver-no-defer/index.js index fb640ccf4a6..cf3c1f39b13 100644 --- a/packages/core/integration-tests/test/integration/resolver-canDefer/node_modules/parcel-resolver-no-defer/index.js +++ b/packages/core/integration-tests/test/integration/resolver-canDefer/node_modules/parcel-resolver-no-defer/index.js @@ -5,7 +5,7 @@ const path = require('path'); const {default: NodeResolver} = require('@parcel/node-resolver-core'); module.exports = new Resolver({ - async resolve({dependency, options, filePath}) { + async resolve({dependency, options, specifier}) { let mainFields = ['source', 'browser', 'module', 'main']; const resolver = new NodeResolver({ @@ -15,8 +15,8 @@ module.exports = new Resolver({ mainFields, }); let result = await resolver.resolve({ - filename: filePath, - isURL: dependency.specifierType === 'url', + filename: specifier, + specifierType: dependency.specifierType, parent: dependency.sourcePath, env: dependency.env, }); diff --git a/packages/core/integration-tests/test/integration/swc-helpers/yarn.lock b/packages/core/integration-tests/test/integration/swc-helpers/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index 5f948d2abd3..808996bbb84 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -4571,7 +4571,7 @@ describe('javascript', function() { name: 'BuildError', diagnostics: [ { - message: 'Unknown pipeline: strange-pipeline.', + message: "Failed to resolve 'strange-pipeline:./b.js' from './a.js'", origin: '@parcel/core', codeFrames: [ { @@ -4592,6 +4592,10 @@ describe('javascript', function() { }, ], }, + { + message: "Unknown url scheme or pipeline 'strange-pipeline:'", + origin: '@parcel/resolver-default', + }, ], }); }); diff --git a/packages/core/integration-tests/test/transpilation.js b/packages/core/integration-tests/test/transpilation.js index 6b6865d7b54..5397e170279 100644 --- a/packages/core/integration-tests/test/transpilation.js +++ b/packages/core/integration-tests/test/transpilation.js @@ -258,7 +258,7 @@ describe('transpilation', function() { .slice(2), ); await outputFS.mkdirp(dir); - ncp(path.join(__dirname, '/integration/swc-helpers'), dir); + await ncp(path.join(__dirname, '/integration/swc-helpers'), dir); await bundle(path.join(dir, 'index.js'), { mode: 'production', inputFS: overlayFS, diff --git a/packages/core/types/index.js b/packages/core/types/index.js index bbd7cef5f1f..2db2bfe7b88 100644 --- a/packages/core/types/index.js +++ b/packages/core/types/index.js @@ -1449,14 +1449,19 @@ export type FileCreateInvalidation = * @section resolver */ export type ResolveResult = {| - /** An absolute path to the file. */ + /** An absolute path to the resolved file. */ +filePath?: FilePath, + /** An optional named pipeline to use to compile the resolved file. */ +pipeline?: ?string, + /** Query parameters to be used by transformers when compiling the resolved file. */ + +query?: QueryParameters, + /** Whether the resolved file should be excluded from the build. */ +isExcluded?: boolean, + /** Overrides the priority set on the dependency. */ +priority?: DependencyPriority, /** Corresponds to BaseAsset's sideEffects. */ +sideEffects?: boolean, - /** A resolver might want to resolve to a dummy, in this case filePath is rather "resolve from". */ + /** The code of the resolved asset. If provided, this is used rather than reading the file from disk. */ +code?: string, /** Whether this dependency can be deferred by Parcel itself (true by default). */ +canDefer?: boolean, @@ -1464,7 +1469,9 @@ export type ResolveResult = {| +diagnostics?: Diagnostic | Array, /** Is spread (shallowly merged) onto the request's dependency.meta */ +meta?: JSONObject, + /** A list of file paths or patterns that should invalidate the resolution if created. */ +invalidateOnFileCreate?: Array, + /** A list of files that should invalidate the resolution if modified or deleted. */ +invalidateOnFileChange?: Array, |}; @@ -1595,7 +1602,7 @@ export type Resolver = {| dependency: Dependency, options: PluginOptions, logger: PluginLogger, - filePath: FilePath, + specifier: FilePath, pipeline: ?string, |}): Async, |}; diff --git a/packages/core/utils/src/alternatives.js b/packages/core/utils/src/alternatives.js index a0f8b9ec0c0..14f2740a0f0 100644 --- a/packages/core/utils/src/alternatives.js +++ b/packages/core/utils/src/alternatives.js @@ -63,6 +63,7 @@ async function findAllFilesUp({ maxlength, collected, leadingDotSlash = true, + includeDirectories = true, }: {| fs: FileSystem, dir: string, @@ -71,6 +72,7 @@ async function findAllFilesUp({ maxlength: number, collected: Array, leadingDotSlash?: boolean, + includeDirectories?: boolean, |}): Promise { let dirContent = (await fs.readdir(dir)).sort(); return Promise.all( @@ -80,7 +82,7 @@ async function findAllFilesUp({ if (relativeFilePath.length < maxlength) { let stats = await fs.stat(fullPath); let isDir = stats.isDirectory(); - if (isDir || stats.isFile()) { + if ((isDir && includeDirectories) || stats.isFile()) { collected.push(relativeFilePath); } @@ -106,6 +108,8 @@ export async function findAlternativeFiles( dir: string, projectRoot: string, leadingDotSlash?: boolean = true, + includeDirectories?: boolean = true, + includeExtension?: boolean = false, ): Promise> { let potentialFiles: Array = []; // Find our root, we won't recommend files above the package root as that's bad practise @@ -125,9 +129,10 @@ export async function findAlternativeFiles( maxlength: fileSpecifier.length + 10, collected: potentialFiles, leadingDotSlash, + includeDirectories, }); - if (path.extname(fileSpecifier) === '') { + if (path.extname(fileSpecifier) === '' && !includeExtension) { potentialFiles = potentialFiles.map(p => { let ext = path.extname(p); return ext.length > 0 ? p.slice(0, -ext.length) : p; diff --git a/packages/packagers/css/src/CSSPackager.js b/packages/packagers/css/src/CSSPackager.js index f41b76c3c4f..5030953d4c8 100644 --- a/packages/packagers/css/src/CSSPackager.js +++ b/packages/packagers/css/src/CSSPackager.js @@ -28,8 +28,22 @@ export default (new Packager({ let queue = new PromiseQueue({ maxConcurrent: 32, }); - bundle.traverseAssets({ - exit: asset => { + let hoistedImports = []; + bundle.traverse({ + exit: node => { + if (node.type === 'dependency') { + // Hoist unresolved external dependencies (i.e. http: imports) + if ( + node.value.priority === 'sync' && + !bundleGraph.getResolvedAsset(node.value, bundle) + ) { + hoistedImports.push(node.value.specifier); + } + return; + } + + let asset = node.value; + // Figure out which media types this asset was imported with. // We only want to import the asset once, so group them all together. let media = []; @@ -75,6 +89,12 @@ export default (new Packager({ let contents = ''; let map = new SourceMap(options.projectRoot); let lineOffset = 0; + + for (let url of hoistedImports) { + contents += `@import "${url}";\n`; + lineOffset++; + } + for (let [asset, code, mapBuffer] of outputs) { contents += code + '\n'; if (bundle.env.sourceMap) { diff --git a/packages/resolvers/default/src/DefaultResolver.js b/packages/resolvers/default/src/DefaultResolver.js index bfe30b809e6..3d6585b4b14 100644 --- a/packages/resolvers/default/src/DefaultResolver.js +++ b/packages/resolvers/default/src/DefaultResolver.js @@ -8,7 +8,7 @@ import NodeResolver from '@parcel/node-resolver-core'; const WEBPACK_IMPORT_REGEX = /\S+-loader\S*!\S+/g; export default (new Resolver({ - resolve({dependency, options, filePath}) { + resolve({dependency, options, specifier}) { if (WEBPACK_IMPORT_REGEX.test(dependency.specifier)) { throw new Error( `The import path: ${dependency.specifier} is using webpack specific loader import syntax, which isn't supported by Parcel.`, @@ -18,13 +18,18 @@ export default (new Resolver({ const resolver = new NodeResolver({ fs: options.inputFS, projectRoot: options.projectRoot, - extensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'css', 'styl', 'vue'], + // Extensions are always required in URL dependencies. + extensions: + dependency.specifierType === 'commonjs' || + dependency.specifierType === 'esm' + ? ['ts', 'tsx', 'js', 'jsx', 'json'] + : [], mainFields: ['source', 'browser', 'module', 'main'], }); return resolver.resolve({ - filename: filePath, - isURL: dependency.specifierType === 'url', + filename: specifier, + specifierType: dependency.specifierType, parent: dependency.resolveFrom, env: dependency.env, sourcePath: dependency.sourcePath, diff --git a/packages/resolvers/glob/src/GlobResolver.js b/packages/resolvers/glob/src/GlobResolver.js index 9690bbf9d6d..134aa120574 100644 --- a/packages/resolvers/glob/src/GlobResolver.js +++ b/packages/resolvers/glob/src/GlobResolver.js @@ -7,8 +7,8 @@ import nullthrows from 'nullthrows'; import ThrowableDiagnostic from '@parcel/diagnostic'; export default (new Resolver({ - async resolve({dependency, options, filePath, pipeline}) { - if (!isGlob(filePath)) { + async resolve({dependency, options, specifier, pipeline}) { + if (!isGlob(specifier)) { return; } @@ -47,13 +47,13 @@ export default (new Resolver({ }); } - filePath = path.resolve(path.dirname(sourceFile), filePath); - let normalized = normalizeSeparators(filePath); + specifier = path.resolve(path.dirname(sourceFile), specifier); + let normalized = normalizeSeparators(specifier); let files = await glob(normalized, options.inputFS, { onlyFiles: true, }); - let dir = path.dirname(filePath); + let dir = path.dirname(specifier); let results = files.map(file => { let relative = relativePath(dir, file); if (pipeline) { @@ -88,7 +88,9 @@ export default (new Resolver({ return { filePath: path.join( dir, - path.basename(filePath, path.extname(filePath)) + '.' + sourceAssetType, + path.basename(specifier, path.extname(specifier)) + + '.' + + sourceAssetType, ), code, invalidateOnFileCreate: [{glob: normalized}], diff --git a/packages/transformers/css/src/CSSTransformer.js b/packages/transformers/css/src/CSSTransformer.js index c7fbe10c1df..a5437582245 100644 --- a/packages/transformers/css/src/CSSTransformer.js +++ b/packages/transformers/css/src/CSSTransformer.js @@ -5,11 +5,7 @@ import type {FilePath} from '@parcel/types'; import SourceMap from '@parcel/source-map'; import {Transformer} from '@parcel/plugin'; -import { - createDependencyLocation, - isURL, - remapSourceLocation, -} from '@parcel/utils'; +import {createDependencyLocation, remapSourceLocation} from '@parcel/utils'; import postcss from 'postcss'; import nullthrows from 'nullthrows'; import valueParser from 'postcss-value-parser'; @@ -108,35 +104,29 @@ export default (new Transformer({ throw new Error('Could not find import name for ' + String(rule)); } - if (isURL(specifier)) { - name.value = asset.addURLDependency(specifier, { - loc: createLoc(nullthrows(rule.source.start), asset.filePath, 0, 8), - }); - } else { - // If this came from an inline

🚨 Parcel encountered errors

<% errors.forEach(function(error){ %>

<%- error.message %>

-
- <%- error.stack %> -
-
+
<%- error.stack %>
+
    <% error.hints.forEach(function(hint){ %> -
    <%- hint %>
    +
  • <%- hint %>
  • <% }); %> -
+ + <% if (error.documentation) { %> + + <% } %> <% }); %> diff --git a/packages/runtimes/hmr/src/loaders/hmr-runtime.js b/packages/runtimes/hmr/src/loaders/hmr-runtime.js index 3e07d8c0bd9..53e2793f9a3 100644 --- a/packages/runtimes/hmr/src/loaders/hmr-runtime.js +++ b/packages/runtimes/hmr/src/loaders/hmr-runtime.js @@ -183,12 +183,15 @@ function createErrorOverlay(diagnostics) {
🚨 ${diagnostic.message}
-
-          ${stack}
-        
+
${stack}
- ${diagnostic.hints.map(hint => '
' + hint + '
').join('')} + ${diagnostic.hints.map(hint => '
💡 ' + hint + '
').join('')}
+ ${ + diagnostic.documentation + ? `` + : '' + } `; } diff --git a/packages/transformers/babel/package.json b/packages/transformers/babel/package.json index 639bc1a4aac..59f889930f8 100644 --- a/packages/transformers/babel/package.json +++ b/packages/transformers/babel/package.json @@ -26,6 +26,7 @@ "@babel/plugin-transform-flow-strip-types": "^7.0.0", "@babel/traverse": "^7.0.0", "@parcel/babel-ast-utils": "2.0.0-rc.0", + "@parcel/diagnostic": "2.0.0-rc.0", "@parcel/plugin": "2.0.0-rc.0", "@parcel/source-map": "2.0.0-rc.6", "@parcel/utils": "2.0.0-rc.0", diff --git a/packages/transformers/babel/src/config.js b/packages/transformers/babel/src/config.js index 7e3737faa31..8941f56247d 100644 --- a/packages/transformers/babel/src/config.js +++ b/packages/transformers/babel/src/config.js @@ -2,11 +2,13 @@ import type {Config, PluginOptions, PluginLogger} from '@parcel/types'; import typeof * as BabelCore from '@babel/core'; +import type {Diagnostic} from '@parcel/diagnostic'; import type {BabelConfig} from './types'; import path from 'path'; import * as internalBabelCore from '@babel/core'; import {hashObject, relativePath, resolveConfig} from '@parcel/utils'; +import {md, generateJSONCodeHighlights} from '@parcel/diagnostic'; import isJSX from './jsx'; import getFlowOptions from './flow'; @@ -195,6 +197,7 @@ export async function load( config.setCacheKey(JSON.stringify(Date.now())); config.invalidateOnStartup(); } else { + await warnOnRedundantPlugins(options.inputFS, partialConfig, logger); definePluginDependencies(config, partialConfig.options, options); config.setCacheKey(hashObject(partialConfig.options)); } @@ -285,3 +288,142 @@ function definePluginDependencies(config, babelConfig: ?BabelConfig, options) { }); } } + +const redundantPresets = new Set([ + '@babel/preset-env', + '@babel/preset-react', + '@babel/preset-typescript', + '@parcel/babel-preset-env', +]); + +async function warnOnRedundantPlugins(fs, babelConfig, logger) { + if (babelConfig == null) { + return; + } + + let configPath = babelConfig.config ?? babelConfig.babelrc; + if (!configPath) { + return; + } + + let presets = babelConfig.options.presets || []; + let plugins = babelConfig.options.plugins || []; + let foundRedundantPresets = new Set(); + + let filteredPresets = presets.filter(preset => { + if (redundantPresets.has(preset.file.request)) { + foundRedundantPresets.add(preset.file.request); + return false; + } + + return true; + }); + + let filePath = path.relative(process.cwd(), configPath); + let diagnostics: Array = []; + + if ( + filteredPresets.length === 0 && + foundRedundantPresets.size > 0 && + plugins.length === 0 + ) { + diagnostics.push({ + message: md`Parcel includes transpilation by default. Babel config __${filePath}__ contains only redundant presets. Deleting it may significantly improve build performance.`, + codeFrames: [ + { + filePath: configPath, + codeHighlights: await getCodeHighlights( + fs, + configPath, + foundRedundantPresets, + ), + }, + ], + hints: [md`Delete __${filePath}__`], + documentationURL: + 'https://v2.parceljs.org/languages/javascript/#default-presets', + }); + } else if (foundRedundantPresets.size > 0) { + diagnostics.push({ + message: md`Parcel includes transpilation by default. Babel config __${filePath}__ includes the following redundant presets: ${[ + ...foundRedundantPresets, + ].map(p => + md.underline(p), + )}. Removing these may improve build performance.`, + codeFrames: [ + { + filePath: configPath, + codeHighlights: await getCodeHighlights( + fs, + configPath, + foundRedundantPresets, + ), + }, + ], + hints: [md`Remove the above presets from __${filePath}__`], + documentationURL: + 'https://v2.parceljs.org/languages/javascript/#default-presets', + }); + } + + if (foundRedundantPresets.has('@babel/preset-env')) { + diagnostics.push({ + message: + "@babel/preset-env does not support Parcel's targets, which will likely result in unnecessary transpilation and larger bundle sizes.", + codeFrames: [ + { + filePath: babelConfig.config ?? babelConfig.babelrc, + codeHighlights: await getCodeHighlights( + fs, + babelConfig.config ?? babelConfig.babelrc, + new Set(['@babel/preset-env']), + ), + }, + ], + hints: [ + `Either remove __@babel/preset-env__ to use Parcel's builtin transpilation, or replace with __@parcel/babel-preset-env__`, + ], + documentationURL: + 'https://v2.parceljs.org/languages/javascript/#custom-plugins', + }); + } + + if (diagnostics.length > 0) { + logger.warn(diagnostics); + } +} + +async function getCodeHighlights(fs, filePath, redundantPresets) { + let ext = path.extname(filePath); + if (ext !== '.js' && ext !== '.cjs' && ext !== '.mjs') { + let contents = await fs.readFile(filePath, 'utf8'); + let json = JSON.parse(contents); + + let presets = json.presets || []; + let pointers = []; + for (let i = 0; i < presets.length; i++) { + if (Array.isArray(presets[i]) && redundantPresets.has(presets[i][0])) { + pointers.push({type: 'value', key: `/presets/${i}/0`}); + } else if (redundantPresets.has(presets[i])) { + pointers.push({type: 'value', key: `/presets/${i}`}); + } + } + + if (pointers.length > 0) { + return generateJSONCodeHighlights(contents, pointers); + } + } + + return [ + { + start: { + line: 1, + column: 1, + }, + end: { + line: 1, + column: 1, + }, + }, + ]; +} diff --git a/packages/transformers/js/core/src/dependency_collector.rs b/packages/transformers/js/core/src/dependency_collector.rs index c16685aa8be..967573ce192 100644 --- a/packages/transformers/js/core/src/dependency_collector.rs +++ b/packages/transformers/js/core/src/dependency_collector.rs @@ -207,6 +207,9 @@ impl<'a> DependencyCollector<'a> { hints: None, show_environment: true, severity: DiagnosticSeverity::Error, + documentation_url: Some(String::from( + "https://v2.parceljs.org/languages/javascript/#classic-scripts", + )), }); } } @@ -356,32 +359,52 @@ impl<'a> Fold for DependencyCollector<'a> { } "importScripts" => { if self.config.is_worker { - let msg = if self.config.source_type == SourceType::Script { + let (msg, span) = if self.config.source_type == SourceType::Script { // Ignore if argument is not a string literal. - if let Some(ast::ExprOrSpread { expr, .. }) = node.args.get(0) { + let span = if let Some(ast::ExprOrSpread { expr, .. }) = node.args.get(0) { match &**expr { - Lit(ast::Lit::Str(_)) => {} + Lit(ast::Lit::Str(ast::Str { value, span, .. })) => { + // Ignore absolute URLs. + if value.starts_with("http:") + || value.starts_with("https:") + || value.starts_with("//") + { + return node.fold_children_with(self); + } + span + } _ => { return node.fold_children_with(self); } } - } - - "importScripts() is not supported in worker scripts." + } else { + return node.fold_children_with(self); + }; + + ( + "Argument to importScripts() must be a fully qualified URL.", + *span, + ) } else { - "importScripts() is not supported in module workers." + ( + "importScripts() is not supported in module workers.", + node.span, + ) }; self.diagnostics.push(Diagnostic { message: msg.to_string(), code_highlights: Some(vec![CodeHighlight { message: None, - loc: SourceLocation::from(self.source_map, node.span), + loc: SourceLocation::from(self.source_map, span), }]), hints: Some(vec![String::from( "Use a static `import`, or dynamic `import()` instead.", )]), show_environment: self.config.source_type == SourceType::Script, severity: DiagnosticSeverity::Error, + documentation_url: Some(String::from( + "https://v2.parceljs.org/languages/javascript/#classic-script-workers", + )), }); } @@ -535,10 +558,16 @@ impl<'a> Fold for DependencyCollector<'a> { s } else if let Lit(lit) = &*arg.expr { if let ast::Lit::Str(str_) = lit { - let msg = if kind == DependencyKind::ServiceWorker { - "Registering service workers with a string literal is not supported." + let (msg, docs) = if kind == DependencyKind::ServiceWorker { + ( + "Registering service workers with a string literal is not supported.", + "https://v2.parceljs.org/languages/javascript/#service-workers", + ) } else { - "Registering worklets with a string literal is not supported." + ( + "Registering worklets with a string literal is not supported.", + "http://localhost:8080/languages/javascript/#worklets", + ) }; self.diagnostics.push(Diagnostic { message: msg.to_string(), @@ -552,6 +581,7 @@ impl<'a> Fold for DependencyCollector<'a> { )]), show_environment: false, severity: DiagnosticSeverity::Error, + documentation_url: Some(String::from(docs)), }); return node; } else { @@ -723,6 +753,9 @@ impl<'a> Fold for DependencyCollector<'a> { )]), show_environment: false, severity: DiagnosticSeverity::Error, + documentation_url: Some(String::from( + "https://v2.parceljs.org/languages/javascript/#web-workers", + )), }); return node; } else { @@ -1226,6 +1259,9 @@ impl<'a> DependencyCollector<'a> { hints: None, show_environment: true, severity: DiagnosticSeverity::Error, + documentation_url: Some(String::from( + "https://v2.parceljs.org/languages/javascript/#classic-scripts", + )), }) } true diff --git a/packages/transformers/js/core/src/env_replacer.rs b/packages/transformers/js/core/src/env_replacer.rs index 7d90274f143..b4aec4c9d57 100644 --- a/packages/transformers/js/core/src/env_replacer.rs +++ b/packages/transformers/js/core/src/env_replacer.rs @@ -126,7 +126,6 @@ impl<'a> Fold for EnvReplacer<'a> { } } PatOrExpr::Expr(expr) => Some(&**expr), - _ => None, }; if let Some(Expr::Member(MemberExpr { @@ -306,6 +305,7 @@ impl<'a> EnvReplacer<'a> { hints: None, show_environment: false, severity: DiagnosticSeverity::SourceError, + documentation_url: None, }); } } diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index 19df1329367..d39858bc44b 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -170,6 +170,7 @@ impl<'a> Fold for Hoist<'a> { hints: None, show_environment: false, severity: DiagnosticSeverity::Error, + documentation_url: None, }) } } diff --git a/packages/transformers/js/core/src/lib.rs b/packages/transformers/js/core/src/lib.rs index a22c7c906c9..a209a966ea0 100644 --- a/packages/transformers/js/core/src/lib.rs +++ b/packages/transformers/js/core/src/lib.rs @@ -195,6 +195,7 @@ pub fn transform(config: Config) -> Result { hints, show_environment: false, severity: DiagnosticSeverity::Error, + documentation_url: None, } }) .collect(); diff --git a/packages/transformers/js/core/src/utils.rs b/packages/transformers/js/core/src/utils.rs index a91044f0832..8d3d59cafc4 100644 --- a/packages/transformers/js/core/src/utils.rs +++ b/packages/transformers/js/core/src/utils.rs @@ -187,6 +187,7 @@ pub struct Diagnostic { pub hints: Option>, pub show_environment: bool, pub severity: DiagnosticSeverity, + pub documentation_url: Option, } #[derive(Serialize, Deserialize, Debug, Eq, PartialEq)] diff --git a/packages/transformers/js/src/JSTransformer.js b/packages/transformers/js/src/JSTransformer.js index 6d995337d14..10791a46390 100644 --- a/packages/transformers/js/src/JSTransformer.js +++ b/packages/transformers/js/src/JSTransformer.js @@ -1,6 +1,7 @@ // @flow import type {JSONObject, EnvMap} from '@parcel/types'; import type {SchemaEntity} from '@parcel/utils'; +import type {Diagnostic} from '@parcel/diagnostic'; import SourceMap from '@parcel/source-map'; import {Transformer} from '@parcel/plugin'; import {init, transform} from '../native'; @@ -440,7 +441,7 @@ export default (new Transformer({ message = err?.message || SCRIPT_ERRORS.browser.message; } - let res = { + let res: Diagnostic = { message, codeFrames: [ { @@ -458,9 +459,13 @@ export default (new Transformer({ hints: diagnostic.hints, }; + if (diagnostic.documentation_url) { + res.documentationURL = diagnostic.documentation_url; + } + if (diagnostic.show_environment) { if (asset.env.loc && asset.env.loc.filePath !== asset.filePath) { - res.codeFrames.push({ + res.codeFrames?.push({ filePath: asset.env.loc.filePath, codeHighlights: [ { @@ -584,10 +589,13 @@ export default (new Transformer({ let env; if (dep.kind === 'DynamicImport') { - if (asset.env.isWorklet()) { + // https://html.spec.whatwg.org/multipage/webappapis.html#hostimportmoduledynamically(referencingscriptormodule,-modulerequest,-promisecapability) + if (asset.env.isWorklet() || asset.env.context === 'service-worker') { let loc = convertLoc(dep.loc); let diagnostic = { - message: 'import() is not allowed in worklets.', + message: `import() is not allowed in ${ + asset.env.isWorklet() ? 'worklets' : 'service workers' + }.`, codeFrames: [ { filePath: asset.filePath, From a73259cef6777f651e917534ae55cf320e100e9a Mon Sep 17 00:00:00 2001 From: Chris Wilkinson Date: Sun, 22 Aug 2021 19:20:12 +0100 Subject: [PATCH 12/42] Add SVG transformer (#6595) --- packages/configs/default/index.json | 3 +- packages/configs/default/package.json | 3 +- .../{.parcelrc-svg => .parcelrc-svg-react} | 2 +- .../integration/{svg => svg-react}/icon.svg | 0 .../integration/{svg => svg-react}/index.html | 0 .../{svg => svg-react}/package.json | 0 .../integration/{svg => svg-react}/react.js | 0 .../integration/svg-xml-stylesheet/img.svg | 11 ++++ .../integration/svg-xml-stylesheet/style1.css | 4 ++ .../integration/svg-xml-stylesheet/style2.css | 3 + .../integration/svg-xml-stylesheet/style3.css | 3 + .../integration/svg-xml-stylesheet/style4.css | 3 + .../test/integration/svg/circle.svg | 8 +++ .../test/integration/svg/other1.html | 2 + .../test/integration/svg/other2.html | 2 + .../test/integration/svg/square.svg | 6 ++ .../core/integration-tests/test/svg-react.js | 22 +++++++ packages/core/integration-tests/test/svg.js | 66 +++++++++++++++---- packages/transformers/svg/package.json | 30 +++++++++ .../transformers/svg/src/SVGTransformer.js | 46 +++++++++++++ packages/transformers/svg/src/dependencies.js | 56 ++++++++++++++++ 21 files changed, 253 insertions(+), 17 deletions(-) rename packages/core/integration-tests/test/integration/custom-configs/{.parcelrc-svg => .parcelrc-svg-react} (61%) rename packages/core/integration-tests/test/integration/{svg => svg-react}/icon.svg (100%) rename packages/core/integration-tests/test/integration/{svg => svg-react}/index.html (100%) rename packages/core/integration-tests/test/integration/{svg => svg-react}/package.json (100%) rename packages/core/integration-tests/test/integration/{svg => svg-react}/react.js (100%) create mode 100644 packages/core/integration-tests/test/integration/svg-xml-stylesheet/img.svg create mode 100644 packages/core/integration-tests/test/integration/svg-xml-stylesheet/style1.css create mode 100644 packages/core/integration-tests/test/integration/svg-xml-stylesheet/style2.css create mode 100644 packages/core/integration-tests/test/integration/svg-xml-stylesheet/style3.css create mode 100644 packages/core/integration-tests/test/integration/svg-xml-stylesheet/style4.css create mode 100644 packages/core/integration-tests/test/integration/svg/circle.svg create mode 100644 packages/core/integration-tests/test/integration/svg/other1.html create mode 100644 packages/core/integration-tests/test/integration/svg/other2.html create mode 100644 packages/core/integration-tests/test/integration/svg/square.svg create mode 100644 packages/core/integration-tests/test/svg-react.js create mode 100644 packages/transformers/svg/package.json create mode 100644 packages/transformers/svg/src/SVGTransformer.js create mode 100644 packages/transformers/svg/src/dependencies.js diff --git a/packages/configs/default/index.json b/packages/configs/default/index.json index cd283904975..8241705e16e 100644 --- a/packages/configs/default/index.json +++ b/packages/configs/default/index.json @@ -40,6 +40,7 @@ "style:*.vue": ["@parcel/transformer-vue"], "custom:*.vue": ["@parcel/transformer-vue"], "*.{png,jpg,jpeg,webp}": ["@parcel/transformer-image"], + "*.svg": ["@parcel/transformer-svg"], "url:*": ["...", "@parcel/transformer-raw"] }, "namers": ["@parcel/namer-default"], @@ -60,7 +61,7 @@ "*.css": "@parcel/packager-css", "*.{js,mjs,cjs}": "@parcel/packager-js", "*.ts": "@parcel/packager-ts", - "*.{jsonld,webmanifest}": "@parcel/packager-raw-url", + "*.{jsonld,svg,webmanifest}": "@parcel/packager-raw-url", "*": "@parcel/packager-raw" }, "resolvers": ["@parcel/resolver-default"], diff --git a/packages/configs/default/package.json b/packages/configs/default/package.json index 0eacdc81a48..c8ea8a451fe 100644 --- a/packages/configs/default/package.json +++ b/packages/configs/default/package.json @@ -41,7 +41,8 @@ "@parcel/transformer-postcss": "2.0.0-rc.0", "@parcel/transformer-posthtml": "2.0.0-rc.0", "@parcel/transformer-raw": "2.0.0-rc.0", - "@parcel/transformer-react-refresh-wrap": "2.0.0-rc.0" + "@parcel/transformer-react-refresh-wrap": "2.0.0-rc.0", + "@parcel/transformer-svg": "2.0.0-rc.0" }, "parcelDependencies": { "@parcel/optimizer-data-url": "2.0.0-rc.0", diff --git a/packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg b/packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg-react similarity index 61% rename from packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg rename to packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg-react index a12970cd1a4..c11e89a36f8 100644 --- a/packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg +++ b/packages/core/integration-tests/test/integration/custom-configs/.parcelrc-svg-react @@ -1,7 +1,7 @@ { "extends": "@parcel/config-default", "transformers": { - "*.svg": ["@parcel/transformer-svg-react"] + "*.svg": ["...", "@parcel/transformer-svg-react"] }, "reporters": [] } diff --git a/packages/core/integration-tests/test/integration/svg/icon.svg b/packages/core/integration-tests/test/integration/svg-react/icon.svg similarity index 100% rename from packages/core/integration-tests/test/integration/svg/icon.svg rename to packages/core/integration-tests/test/integration/svg-react/icon.svg diff --git a/packages/core/integration-tests/test/integration/svg/index.html b/packages/core/integration-tests/test/integration/svg-react/index.html similarity index 100% rename from packages/core/integration-tests/test/integration/svg/index.html rename to packages/core/integration-tests/test/integration/svg-react/index.html diff --git a/packages/core/integration-tests/test/integration/svg/package.json b/packages/core/integration-tests/test/integration/svg-react/package.json similarity index 100% rename from packages/core/integration-tests/test/integration/svg/package.json rename to packages/core/integration-tests/test/integration/svg-react/package.json diff --git a/packages/core/integration-tests/test/integration/svg/react.js b/packages/core/integration-tests/test/integration/svg-react/react.js similarity index 100% rename from packages/core/integration-tests/test/integration/svg/react.js rename to packages/core/integration-tests/test/integration/svg-react/react.js diff --git a/packages/core/integration-tests/test/integration/svg-xml-stylesheet/img.svg b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/img.svg new file mode 100644 index 00000000000..e2dcb3c0a7e --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/img.svg @@ -0,0 +1,11 @@ + + + + + + Should be red and monospace + diff --git a/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style1.css b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style1.css new file mode 100644 index 00000000000..4c6d8c9b1c8 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style1.css @@ -0,0 +1,4 @@ +:root { + fill: red; + font-family: serif; +} diff --git a/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style2.css b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style2.css new file mode 100644 index 00000000000..d3e88e2a234 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style2.css @@ -0,0 +1,3 @@ +:root { + font-family: sans-serif; +} diff --git a/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style3.css b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style3.css new file mode 100644 index 00000000000..f4523b098a4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style3.css @@ -0,0 +1,3 @@ +:root { + font-family: monospace; +} diff --git a/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style4.css b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style4.css new file mode 100644 index 00000000000..2b5e3e9f641 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-xml-stylesheet/style4.css @@ -0,0 +1,3 @@ +:root { + font-family: cursive; +} diff --git a/packages/core/integration-tests/test/integration/svg/circle.svg b/packages/core/integration-tests/test/integration/svg/circle.svg new file mode 100644 index 00000000000..cd0514173c6 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg/circle.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/packages/core/integration-tests/test/integration/svg/other1.html b/packages/core/integration-tests/test/integration/svg/other1.html new file mode 100644 index 00000000000..f4ae7dea450 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg/other1.html @@ -0,0 +1,2 @@ + +Other page 1 diff --git a/packages/core/integration-tests/test/integration/svg/other2.html b/packages/core/integration-tests/test/integration/svg/other2.html new file mode 100644 index 00000000000..7c40cf0f3bf --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg/other2.html @@ -0,0 +1,2 @@ + +Other page 2 diff --git a/packages/core/integration-tests/test/integration/svg/square.svg b/packages/core/integration-tests/test/integration/svg/square.svg new file mode 100644 index 00000000000..af1ab4adf39 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg/square.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/core/integration-tests/test/svg-react.js b/packages/core/integration-tests/test/svg-react.js new file mode 100644 index 00000000000..4de2d507c93 --- /dev/null +++ b/packages/core/integration-tests/test/svg-react.js @@ -0,0 +1,22 @@ +import assert from 'assert'; +import {bundle, outputFS} from '@parcel/test-utils'; +import path from 'path'; + +describe('svg-react', function() { + it('should support transforming SVGs to react components', async function() { + let b = await bundle( + path.join(__dirname, '/integration/svg-react/react.js'), + { + defaultConfig: path.join( + __dirname, + 'integration/custom-configs/.parcelrc-svg-react', + ), + }, + ); + + let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8'); + assert(!file.includes('inkscape')); + assert(file.includes('function SvgIcon')); + assert(file.includes('_react.createElement("svg"')); + }); +}); diff --git a/packages/core/integration-tests/test/svg.js b/packages/core/integration-tests/test/svg.js index 58a84542584..dc90e9b95c5 100644 --- a/packages/core/integration-tests/test/svg.js +++ b/packages/core/integration-tests/test/svg.js @@ -1,10 +1,33 @@ import assert from 'assert'; -import {bundle, outputFS} from '@parcel/test-utils'; +import {assertBundles, bundle, outputFS} from '@parcel/test-utils'; import path from 'path'; describe('svg', function() { + it('should support bundling SVG', async () => { + let b = await bundle(path.join(__dirname, '/integration/svg/circle.svg')); + + assertBundles(b, [ + { + name: 'circle.svg', + assets: ['circle.svg'], + }, + { + name: 'other1.html', + assets: ['other1.html'], + }, + { + type: 'svg', + assets: ['square.svg'], + }, + { + name: 'other2.html', + assets: ['other2.html'], + }, + ]); + }); + it('should minify SVG bundles', async function() { - let b = await bundle(path.join(__dirname, '/integration/svg/index.html'), { + let b = await bundle(path.join(__dirname, '/integration/svg/circle.svg'), { defaultTargetOptions: { shouldOptimize: true, }, @@ -14,7 +37,7 @@ describe('svg', function() { b.getBundles().find(b => b.type === 'svg').filePath, 'utf-8', ); - assert(!file.includes('inkscape')); + assert(!file.includes('comment')); }); it('support SVGO config files', async function() { @@ -35,17 +58,32 @@ describe('svg', function() { assert(file.includes('comment')); }); - it('should support transforming SVGs to react components', async function() { - let b = await bundle(path.join(__dirname, '/integration/svg/react.js'), { - defaultConfig: path.join( - __dirname, - 'integration/custom-configs/.parcelrc-svg', - ), - }); + it('should detect xml-stylesheet processing instructions', async function() { + let b = await bundle( + path.join(__dirname, '/integration/svg-xml-stylesheet/img.svg'), + ); - let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8'); - assert(!file.includes('inkscape')); - assert(file.includes('function SvgIcon')); - assert(file.includes('_react.createElement("svg"')); + assertBundles(b, [ + { + name: 'img.svg', + assets: ['img.svg'], + }, + { + type: 'css', + assets: ['style1.css'], + }, + { + type: 'css', + assets: ['style3.css'], + }, + ]); + + let file = await outputFS.readFile( + b.getBundles().find(b => b.type === 'svg').filePath, + 'utf-8', + ); + + assert(file.includes('= 12.0.0", + "parcel": "^2.0.0-beta.1" + }, + "dependencies": { + "@parcel/plugin": "2.0.0-rc.0", + "nullthrows": "^1.1.1", + "posthtml": "^0.16.4", + "posthtml-parser": "^0.9.0", + "posthtml-render": "^2.0.6", + "semver": "^5.4.1" + } +} diff --git a/packages/transformers/svg/src/SVGTransformer.js b/packages/transformers/svg/src/SVGTransformer.js new file mode 100644 index 00000000000..4b589e1d932 --- /dev/null +++ b/packages/transformers/svg/src/SVGTransformer.js @@ -0,0 +1,46 @@ +// @flow + +import {Transformer} from '@parcel/plugin'; +import nullthrows from 'nullthrows'; +import semver from 'semver'; +import collectDependencies from './dependencies'; +import parse from 'posthtml-parser'; +import render from 'posthtml-render'; + +export default (new Transformer({ + canReuseAST({ast}) { + return ast.type === 'posthtml' && semver.satisfies(ast.version, '^0.4.0'); + }, + + async parse({asset}) { + return { + type: 'posthtml', + version: '0.4.1', + program: parse(await asset.getCode(), { + directives: [ + { + name: /^\?/, + start: '<', + end: '>', + }, + ], + sourceLocations: true, + xmlMode: true, + }), + }; + }, + + async transform({asset}) { + const ast = nullthrows(await asset.getAST()); + + collectDependencies(asset, ast); + + return [asset]; + }, + + generate({ast}) { + return { + content: render(ast.program), + }; + }, +}): Transformer); diff --git a/packages/transformers/svg/src/dependencies.js b/packages/transformers/svg/src/dependencies.js new file mode 100644 index 00000000000..5f31b86236e --- /dev/null +++ b/packages/transformers/svg/src/dependencies.js @@ -0,0 +1,56 @@ +// @flow + +import type {AST, MutableAsset} from '@parcel/types'; +import PostHTML from 'posthtml'; + +// A list of all attributes that may produce a dependency +// Based on https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute +const ATTRS = { + href: ['a', 'use'], + 'xlink:href': ['a', 'use'], +}; + +// Options to be passed to `addDependency` for certain tags + attributes +const OPTIONS = { + a: { + href: {needsStableName: true}, + 'xlink:href': {needsStableName: true}, + }, +}; + +export default function collectDependencies(asset: MutableAsset, ast: AST) { + let isDirty = false; + PostHTML().walk.call(ast.program, node => { + if (typeof node === 'string' && node.startsWith(' { + isDirty = true; + + return asset.addURLDependency(href, {priority: 'parallel'}); + }); + } + + const {tag, attrs} = node; + if (!attrs) { + return node; + } + + for (const attr in attrs) { + // Check for id references + if (attrs[attr][0] === '#') { + continue; + } + + const elements = ATTRS[attr]; + if (elements && elements.includes(node.tag)) { + attrs[attr] = asset.addURLDependency(attrs[attr], OPTIONS[tag]?.[attr]); + isDirty = true; + } + } + + return node; + }); + + if (isDirty) { + asset.setAST(ast); + } +} From 0d5b0d4b528b88d56bcf87aa6522908c7f8df34e Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Sun, 22 Aug 2021 21:05:45 -0700 Subject: [PATCH 13/42] Fix windows tests --- packages/core/integration-tests/test/babel.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/core/integration-tests/test/babel.js b/packages/core/integration-tests/test/babel.js index 47bea843b2f..09fe260eb6f 100644 --- a/packages/core/integration-tests/test/babel.js +++ b/packages/core/integration-tests/test/babel.js @@ -16,6 +16,7 @@ import Logger from '@parcel/logger'; import os from 'os'; import {spawnSync} from 'child_process'; import tempy from 'tempy'; +import {md} from '@parcel/diagnostic'; const parcelCli = require.resolve('parcel/src/bin.js'); const inputDir = path.join(__dirname, '/input'); @@ -586,7 +587,7 @@ describe('babel', function() { diagnostics: [ { origin: '@parcel/transformer-babel', - message: `Parcel includes transpilation by default. Babel config __${path.relative( + message: md`Parcel includes transpilation by default. Babel config __${path.relative( process.cwd(), babelrcPath, )}__ contains only redundant presets. Deleting it may significantly improve build performance.`, @@ -608,7 +609,9 @@ describe('babel', function() { ], }, ], - hints: ['Delete __test/integration/babel-warn-all/.babelrc__'], + hints: [ + md`Delete __${path.relative(process.cwd(), babelrcPath)}__`, + ], documentationURL: 'https://v2.parceljs.org/languages/javascript/#default-presets', }, @@ -665,7 +668,7 @@ describe('babel', function() { diagnostics: [ { origin: '@parcel/transformer-babel', - message: `Parcel includes transpilation by default. Babel config __${path.relative( + message: md`Parcel includes transpilation by default. Babel config __${path.relative( process.cwd(), babelrcPath, )}__ includes the following redundant presets: __@parcel/babel-preset-env__. Removing these may improve build performance.`, @@ -688,7 +691,7 @@ describe('babel', function() { }, ], hints: [ - `Remove the above presets from __${path.relative( + md`Remove the above presets from __${path.relative( process.cwd(), babelrcPath, )}__`, From 18320b437397a207ec3e80ef8cd08bffe3dd9678 Mon Sep 17 00:00:00 2001 From: Jasper De Moor Date: Mon, 23 Aug 2021 06:11:33 +0200 Subject: [PATCH 14/42] fix: process meta tag dependencies (#6724) --- packages/core/integration-tests/test/html.js | 14 +++++++-- .../test/integration/html-meta/index.html | 2 ++ .../test/integration/html-meta/logo.svg | 1 + .../transformers/html/src/dependencies.js | 31 ++++++++++++------- 4 files changed, 34 insertions(+), 14 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/html-meta/logo.svg diff --git a/packages/core/integration-tests/test/html.js b/packages/core/integration-tests/test/html.js index 076454d5d4d..3cb53488031 100644 --- a/packages/core/integration-tests/test/html.js +++ b/packages/core/integration-tests/test/html.js @@ -170,7 +170,7 @@ describe('html', function() { assert(//.test(html)); }); - it('should support meta tag with none content', async function() { + it('should support meta tags', async function() { let b = await bundle( path.join(__dirname, '/integration/html-meta/index.html'), ); @@ -180,13 +180,23 @@ describe('html', function() { name: 'index.html', assets: ['index.html'], }, + { + name: 'logo.svg', + assets: ['logo.svg'], + }, ]); let html = await outputFS.readFile( path.join(distDir, 'index.html'), 'utf8', ); - assert(//.test(html)); + assert(html.includes(``)); + assert(html.includes(``)); + assert( + html.includes( + ``, + ), + ); }); it('should insert sibling CSS bundles for JS files in the HEAD', async function() { diff --git a/packages/core/integration-tests/test/integration/html-meta/index.html b/packages/core/integration-tests/test/integration/html-meta/index.html index 736896f9034..6400510acdd 100644 --- a/packages/core/integration-tests/test/integration/html-meta/index.html +++ b/packages/core/integration-tests/test/integration/html-meta/index.html @@ -1,6 +1,8 @@ + + diff --git a/packages/core/integration-tests/test/integration/html-meta/logo.svg b/packages/core/integration-tests/test/integration/html-meta/logo.svg new file mode 100644 index 00000000000..131c57b7a3c --- /dev/null +++ b/packages/core/integration-tests/test/integration/html-meta/logo.svg @@ -0,0 +1 @@ +Asset 1 \ No newline at end of file diff --git a/packages/transformers/html/src/dependencies.js b/packages/transformers/html/src/dependencies.js index 4068c7c92b0..0abba7f3c07 100644 --- a/packages/transformers/html/src/dependencies.js +++ b/packages/transformers/html/src/dependencies.js @@ -122,19 +122,26 @@ export default function collectDependencies( seen.add(node); if (tag === 'meta') { - if ( - !Object.keys(attrs).some(attr => { - let values = META[attr]; - return ( - values && - values.includes(attrs[attr]) && - attrs.content !== '' && - !(attrs.name === 'msapplication-config' && attrs.content === 'none') - ); - }) - ) { - return node; + const isMetaDependency = Object.keys(attrs).some(attr => { + let values = META[attr]; + return ( + values && + values.includes(attrs[attr]) && + attrs.content !== '' && + !(attrs.name === 'msapplication-config' && attrs.content === 'none') + ); + }); + if (isMetaDependency) { + const metaAssetUrl = attrs.content; + if (metaAssetUrl) { + attrs.content = asset.addURLDependency(attrs.content, { + needsStableName: true, + }); + isDirty = true; + asset.setAST(ast); + } } + return node; } if ( From 95f5648d775fbea72506c3c4f7a67fe48efa8d43 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Mon, 23 Aug 2021 06:12:16 +0200 Subject: [PATCH 15/42] Bump swc (#6694) --- Cargo.lock | 186 +++++++++++-------- packages/core/integration-tests/package.json | 2 +- packages/transformers/js/core/Cargo.toml | 6 +- packages/transformers/js/core/src/hoist.rs | 96 +++++----- yarn.lock | 50 +---- 5 files changed, 166 insertions(+), 174 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c81c09b5edc..282c23ad761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,17 @@ dependencies = [ "regex", ] +[[package]] +name = "ahash" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "0.7.18" @@ -23,9 +34,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" [[package]] name = "arrayvec" @@ -78,9 +89,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" @@ -105,9 +116,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" [[package]] name = "cfg-if" @@ -275,14 +286,25 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "hermit-abi" @@ -318,9 +340,9 @@ checksum = "1f7280c75fb2e2fc47080ec80ccc481376923acb04501957fc38f935c3de5088" [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", @@ -415,9 +437,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.97" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" [[package]] name = "libmimalloc-sys" @@ -439,9 +461,9 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" @@ -460,9 +482,9 @@ dependencies = [ [[package]] name = "napi" -version = "1.7.5" +version = "1.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59cd02f5de365f9bd6e85f1d11176a9ea70ff63ce55ea4412cb4e00fd5a0fe6c" +checksum = "eb22375ec7cbd8bee4535126bb323e4e62cbf8088d84f0225d4d3226d1619bd5" dependencies = [ "napi-sys", "serde", @@ -563,9 +585,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "ordered-float" -version = "2.5.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f100fcfb41e5385e0991f74981732049f9b896821542a219420491046baafdc2" +checksum = "039f02eb0f69271f26abe3202189275d7aa2258b903cb0281b5de710a2570ff3" dependencies = [ "num-traits", ] @@ -733,9 +755,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" dependencies = [ "unicode-xid", ] @@ -755,7 +777,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", "rand_chacha", "rand_core", @@ -779,7 +801,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", ] [[package]] @@ -871,9 +893,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" dependencies = [ "serde_derive", ] @@ -901,9 +923,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" dependencies = [ "proc-macro2", "quote", @@ -912,9 +934,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" dependencies = [ "itoa", "ryu", @@ -923,9 +945,9 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16" +checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" dependencies = [ "block-buffer", "cfg-if 1.0.0", @@ -936,9 +958,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" +checksum = "729a25c17d72b06c68cb47955d44fda88ad2d3e7d77e025663fdd69b93dd71a1" [[package]] name = "smallvec" @@ -1052,10 +1074,11 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.10.21" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526ac4386aca6a792d75bb3bd5cb72eb170e2029f4ce0f6a9d280923da4b0ce8" +checksum = "0fc89b8c9f2fa3fc646e7d1a05ebc2063b1396b3ba5277afc741505bd7414fff" dependencies = [ + "ahash", "ast_node", "atty", "cfg-if 0.1.10", @@ -1078,9 +1101,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.47.0" +version = "0.49.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab98b7f6777222431bdf193bbfc6046af53cc105c8702390a9109d1a4511329b" +checksum = "3efef728f69665d765c52b233155dcb3290424f56a9f978ecfbd53f136804461" dependencies = [ "is-macro", "num-bigint", @@ -1092,9 +1115,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.60.1" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e84b5477973503f94c6a82f02bc6008c148dc3dd5b07bb81fee6f5f93e3a190" +checksum = "96a380bd935ce811c0bc8b961abc97cbf3a8c759213634aa59f5b0601162ba4e" dependencies = [ "bitflags", "num-bigint", @@ -1121,12 +1144,16 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.9.1" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d234e6348de8d954334700f65a35485363de082fd58671c07f060f1fa499f59c" +checksum = "2bc6a797d2df5f60cc9ab6a85aa7a49ab1bcaac8150d184f79a27deba2d21983" dependencies = [ "anyhow", + "dashmap", + "fxhash", + "log", "normpath", + "once_cell", "serde", "serde_json", "swc_atoms", @@ -1137,9 +1164,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.61.1" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82ed9b5648252851ae2cfc066717fcae9c5561be74f496eda64afc791d9b17ed" +checksum = "e0418c8dcb041d74e90c2179290bf3be0e58f2425d1f86843a5e297a13755912" dependencies = [ "either", "enum_kind", @@ -1158,9 +1185,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.27.0" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538902691c3a274a6e80ce7860c91b96977ebd977e1ca7fba77057e425267951" +checksum = "283a609ec84132c2751bdee13a7a81228007206538ef09a1066163602f0d34d8" dependencies = [ "dashmap", "fxhash", @@ -1182,9 +1209,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.57.0" +version = "0.67.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd060899f0cb2994ad9d2c04475e30864549e80dde35a526acdf3a79ec8d722" +checksum = "9c50b45538663ae18d56768c93567312dd5cbf29786678a94cfa610172ba93a4" dependencies = [ "swc_atoms", "swc_common", @@ -1204,9 +1231,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.20.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311b66839a94ea620382ecadb46c001132c21ad15b13f0e04ffe3ad115a8ce78" +checksum = "b5de480c55ae93eb59715cfc8f66965d192bc62cd4c12e33cff9f940f9431e12" dependencies = [ "fxhash", "once_cell", @@ -1223,9 +1250,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.6.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9f7417ff08dd6da5bf7ab96e96bb6ae43cdf484235ded9855d5260011cc0186" +checksum = "cdcbad381d349cbff95f7602bf2d9ad6a40c7df92a391d4af62221bd0d7633a2" dependencies = [ "swc_atoms", "swc_common", @@ -1237,9 +1264,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.23.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f464846be30234400767c1f7785bdfd2d27fef6f3cfb9f4e24a2044c9e8e76d2" +checksum = "4cca0020d15ecb278fcdc4cd55f199f39e0c42ceb9e7f9740416f36120c17ad5" dependencies = [ "arrayvec", "fxhash", @@ -1274,9 +1301,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.24.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22c79be4775f2f6f166c7901706e5cc64cd837e6a26b8f0d7ced224321a39dc2" +checksum = "ac0abb8acb4b72d1ef37971b0bfed8e267ecaab37b3d34bac96205d7b62689e2" dependencies = [ "Inflector", "anyhow", @@ -1296,9 +1323,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.27.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422f1a381ee1782fa5b3d883fb01239e9bca26515932b93e4fa3e956275c684f" +checksum = "fb3b4c8d2613ce06be5cf8160159eb468117ef6257eba744e1bf18125cca31ad" dependencies = [ "dashmap", "fxhash", @@ -1318,9 +1345,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.24.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90a18d71bee10a061894ff92d36fcc54e43197c92f70cdb98309021bff282290" +checksum = "02a8edf26ee1695c0137a829dbb8bb3c6681c1ae55e23ff45e0e0f41308e795f" dependencies = [ "either", "fxhash", @@ -1338,9 +1365,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.25.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e2bf91bc9166722159d919cff5dc0276fd404031c53a0f5c6716fdcdcb3a0a" +checksum = "72eabb27291ac7bef4f1f85e3aa7d335138dde1a1606b7d584e7f414882e5f3c" dependencies = [ "base64 0.13.0", "dashmap", @@ -1361,9 +1388,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.26.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d642e21c1088a040e680e81527a7d7528c3703070d15f93cc56cce7c8591f2" +checksum = "dc043fd29ceac49f13c1c994ba784f404cca3e189dd6cb771bfe905a0f776592" dependencies = [ "fxhash", "serde", @@ -1378,9 +1405,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.38.0" +version = "0.41.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db19d40a76ba6c01ebbbd73981645dd2552cdbfc14605481c7a9b7f6f26bd20e" +checksum = "50bacaf860e4224e1a12bea8730c94de28f990f92685dad57aa572e3473043f7" dependencies = [ "once_cell", "scoped-tls", @@ -1393,9 +1420,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.33.0" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ad83badbeda1123290a73ca6254158ed027f72f1b593f96acddcaed5d49c6a" +checksum = "d51ce688b7c984d0325261edb3ced4195790c7ac76982e269d2114ec04e3ae7c" dependencies = [ "num-bigint", "swc_atoms", @@ -1406,9 +1433,9 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "0.43.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e1c5047fe3f5a6c301a312c278ac018789ba4a6e40e556612e82defda422c" +checksum = "e41615d9e65c7b148950211dacd0b2343a646d84493b9c8efa8795ee1a6e2f4f" dependencies = [ "swc_ecma_ast", "swc_ecma_codegen", @@ -1444,9 +1471,9 @@ dependencies = [ [[package]] name = "swc_visit" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583cfe83f6002e1118559308b88181f34b5936b403b72548cd0259bfcf0ca39e" +checksum = "a423caa0b4585118164dbad8f1ad52b592a9a9370b25decc4d84c6b4309132c0" dependencies = [ "either", "swc_visit_macros", @@ -1488,9 +1515,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" +checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" dependencies = [ "tinyvec_macros", ] @@ -1509,12 +1536,9 @@ checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" [[package]] name = "unicode-bidi" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" -dependencies = [ - "matches", -] +checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" [[package]] name = "unicode-normalization" @@ -1578,6 +1602,12 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "wasm-bindgen" version = "0.2.72" diff --git a/packages/core/integration-tests/package.json b/packages/core/integration-tests/package.json index adb78208f59..00185cbecc6 100644 --- a/packages/core/integration-tests/package.json +++ b/packages/core/integration-tests/package.json @@ -26,7 +26,7 @@ "command-exists": "^1.2.6", "core-js": "^3.2.1", "cross-env": "^7.0.0", - "elm": "^0.19.1-3", + "elm": "^0.19.1-5", "elm-hot": "^1.1.5", "get-port": "^5.0.0", "graphql": "^15.0.0", diff --git a/packages/transformers/js/core/Cargo.toml b/packages/transformers/js/core/Cargo.toml index 1f2872fda6e..279d45252d5 100644 --- a/packages/transformers/js/core/Cargo.toml +++ b/packages/transformers/js/core/Cargo.toml @@ -8,9 +8,9 @@ edition = "2018" crate-type = ["rlib"] [dependencies] -swc_ecmascript = { version = "0.43.0", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils"] } -swc_ecma_preset_env = "0.27.0" -swc_common = { version = "0.10.21", features = ["tty-emitter", "sourcemap"] } +swc_ecmascript = { version = "0.57.0", features = ["parser", "transforms", "module", "optimization", "react", "typescript", "utils", "visit", "codegen", "utils"] } +swc_ecma_preset_env = "0.38.0" +swc_common = { version = "0.11.6", features = ["tty-emitter", "sourcemap"] } swc_atoms = "0.2.6" indoc = "1.0.3" serde = "1.0.123" diff --git a/packages/transformers/js/core/src/hoist.rs b/packages/transformers/js/core/src/hoist.rs index d39858bc44b..10004793bfa 100644 --- a/packages/transformers/js/core/src/hoist.rs +++ b/packages/transformers/js/core/src/hoist.rs @@ -2477,7 +2477,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; let $abc$var$test = { bar: 3 }; @@ -2495,7 +2495,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; console.log($abc$import$558d6cfb8af8a010$3705fc5f2281438d); "#} ); @@ -2510,7 +2510,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; console.log($abc$import$558d6cfb8af8a010$9099ad97b570f7c, $abc$import$558d6cfb8af8a010$9099ad97b570f7c.bar); "#} ); @@ -2530,8 +2530,8 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; - import "abc:bar"; + import "abc:other"; + import "abc:bar"; console.log($abc$import$558d6cfb8af8a010$9099ad97b570f7c); console.log($abc$import$3705fc5f2281438d$9099ad97b570f7c); "#} @@ -2551,10 +2551,10 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; - import "abc:bar"; + import "abc:other"; + import "abc:bar"; console.log($abc$import$558d6cfb8af8a010$9099ad97b570f7c); - import "abc:x"; + import "abc:x"; console.log($abc$import$10b1f2ceae7ab64e); console.log($abc$import$3705fc5f2281438d$9099ad97b570f7c); "#} @@ -2574,7 +2574,7 @@ mod tests { code, indoc! {r#" const $abc$var$x = 4; - import "abc:other"; + import "abc:other"; var $abc$require$bar = $abc$import$558d6cfb8af8a010$3705fc5f2281438d; const $abc$var$baz = 3; console.log($abc$require$bar); @@ -2592,7 +2592,7 @@ mod tests { code, indoc! {r#" const $abc$var$x = 3; - import "abc:other"; + import "abc:other"; const $abc$var$bar = 2; console.log($abc$import$558d6cfb8af8a010$3705fc5f2281438d); "#} @@ -2611,7 +2611,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; const { foo: $abc$var$foo , ...$abc$var$bar } = $abc$import$558d6cfb8af8a010; console.log($abc$var$foo, $abc$var$bar); "#} @@ -2627,7 +2627,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:x"; + import "abc:x"; const { x: { y: $abc$var$z } } = $abc$import$10b1f2ceae7ab64e; console.log($abc$var$z); "#} @@ -2643,7 +2643,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; console.log($abc$import$558d6cfb8af8a010[bar]); "#} ); @@ -2658,7 +2658,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; console.log($abc$import$558d6cfb8af8a010[bar], $abc$import$558d6cfb8af8a010.baz); "#} ); @@ -2684,7 +2684,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; var $abc$require$foo = $abc$import$558d6cfb8af8a010$ba02ad2230917043; console.log($abc$require$foo); "#} @@ -2700,7 +2700,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; const $abc$var$foo = $abc$import$558d6cfb8af8a010[bar]; console.log($abc$var$foo); "#} @@ -2716,7 +2716,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; const { foo: $abc$var$foo } = $abc$import$558d6cfb8af8a010$ba02ad2230917043; console.log($abc$var$foo); "#} @@ -2738,12 +2738,12 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; function $abc$var$x() { const foo = $abc$import$558d6cfb8af8a010; console.log(foo.bar); } - import "abc:bar"; + import "abc:bar"; "#} ); assert_eq!( @@ -2764,7 +2764,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; var $abc$var$foo = (function() { if (Date.now() < 0) { var bar = $abc$import$558d6cfb8af8a010; @@ -2789,7 +2789,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; function $abc$var$x() { const foo = $abc$import$558d6cfb8af8a010$ba02ad2230917043; console.log(foo); @@ -2808,7 +2808,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; function $abc$var$x() { console.log($abc$import$558d6cfb8af8a010$ba02ad2230917043); } @@ -2827,7 +2827,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; function $abc$var$x() { const foo = $abc$import$558d6cfb8af8a010[test]; console.log(foo); @@ -2847,7 +2847,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; function $abc$var$x() { const { foo: foo } = $abc$import$558d6cfb8af8a010; console.log(foo); @@ -2864,8 +2864,8 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:a"; - import "abc:b"; + import "abc:a"; + import "abc:b"; let $abc$var$x = $abc$import$7ac649919d1c80a6 + $abc$import$a91ade93898ecc38; "#} ); @@ -2879,8 +2879,8 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:a"; - import "abc:b"; + import "abc:a"; + import "abc:b"; let $abc$var$x = (!$abc$import$7ac649919d1c80a6, $abc$import$a91ade93898ecc38); "#} ); @@ -2894,8 +2894,8 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:a"; - import "abc:b"; + import "abc:a"; + import "abc:b"; let $abc$var$x = $abc$import$7ac649919d1c80a6 || $abc$import$a91ade93898ecc38; "#} ); @@ -2909,8 +2909,8 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:a"; - import "abc:b"; + import "abc:a"; + import "abc:b"; let $abc$var$x = condition ? $abc$import$7ac649919d1c80a6 : $abc$import$a91ade93898ecc38; "#} ); @@ -2924,7 +2924,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:a"; + import "abc:a"; if (condition) $abc$import$7ac649919d1c80a6; "#} ); @@ -2938,7 +2938,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:y"; + import "abc:y"; for(let x = $abc$import$57bbd0ca114c72e; x < 5; x++){ } "#} @@ -3088,7 +3088,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:bar"; + import "abc:bar"; "#} ); @@ -3101,7 +3101,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:bar"; + import "abc:bar"; "#} ); } @@ -3383,7 +3383,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; async function $abc$var$test() { const x = await $abc$importAsync$558d6cfb8af8a010; console.log(x.foo); @@ -3414,7 +3414,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; async function $abc$var$test() { const x = await $abc$importAsync$558d6cfb8af8a010; console.log(x[foo]); @@ -3445,7 +3445,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; async function $abc$var$test() { const { foo: foo } = await $abc$importAsync$558d6cfb8af8a010; console.log(foo); @@ -3476,7 +3476,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; async function $abc$var$test() { const { foo: bar } = await $abc$importAsync$558d6cfb8af8a010; console.log(bar); @@ -3504,7 +3504,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then((x)=>x.foo ); "#} @@ -3530,7 +3530,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then((x)=>x ); "#} @@ -3556,7 +3556,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(({ foo: foo })=>foo ); "#} @@ -3582,7 +3582,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(({ foo: bar })=>bar ); "#} @@ -3608,7 +3608,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(function(x) { return x.foo; }); @@ -3635,7 +3635,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(function(x) { return x; }); @@ -3662,7 +3662,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(function({ foo: foo }) { }); "#} @@ -3688,7 +3688,7 @@ mod tests { assert_eq!( code, indoc! {r#" - import "abc:other"; + import "abc:other"; $abc$importAsync$558d6cfb8af8a010.then(function({ foo: bar }) { }); "#} diff --git a/yarn.lock b/yarn.lock index ba2a2a6b787..17e9d24dc85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4359,17 +4359,6 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" -css-select@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" - integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== - dependencies: - boolbase "^1.0.0" - css-what "^4.0.0" - domhandler "^4.0.0" - domutils "^2.4.3" - nth-check "^2.0.0" - css-select@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" @@ -4411,11 +4400,6 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== -css-what@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" - integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== - css-what@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" @@ -4985,16 +4969,7 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" -domutils@^2.4.2, domutils@^2.4.3, domutils@^2.5.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" - integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -domutils@^2.6.0: +domutils@^2.4.2, domutils@^2.5.2, domutils@^2.6.0: version "2.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442" integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg== @@ -5093,10 +5068,10 @@ elm-hot@^1.1.5: resolved "https://registry.yarnpkg.com/elm-hot/-/elm-hot-1.1.5.tgz#bba309b592d39b5c3195c3c6f608f36b96c23b89" integrity sha512-HSMlAr6INTV82wkpPNG0zsHoJXo/04GwG7bnhFX8s4zyIbbzuJAovsdo27FAT6/NKx5IVTXGI+IFcK9Z7oN1Tw== -elm@^0.19.1-3: - version "0.19.1-3" - resolved "https://registry.yarnpkg.com/elm/-/elm-0.19.1-3.tgz#2382aa1943bc79974b5d95b0a6acbe010ee16909" - integrity sha512-6y36ewCcVmTOx8lj7cKJs3bhI5qMfoVEigePZ9PhEUNKpwjjML/pU2u2YSpHVAznuCcojoF6KIsrS1Ci7GtVaQ== +elm@^0.19.1-5: + version "0.19.1-5" + resolved "https://registry.yarnpkg.com/elm/-/elm-0.19.1-5.tgz#61f18437222972e20f316f9b2d2c76a781a9991b" + integrity sha512-dyBoPvFiNLvxOStQJdyq28gZEjS/enZXdZ5yyCtNtDEMbFJJVQq4pYNRKvhrKKdlxNot6d96iQe1uczoqO5yvA== dependencies: request "^2.88.0" @@ -12477,20 +12452,7 @@ svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -svgo@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" - integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== - dependencies: - "@trysound/sax" "0.1.1" - chalk "^4.1.0" - commander "^7.1.0" - css-select "^3.1.2" - css-tree "^1.1.2" - csso "^4.2.0" - stable "^0.1.8" - -svgo@^2.4.0: +svgo@^2.3.0, svgo@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.4.0.tgz#0c42653101fd668692c0f69b55b8d7b182ef422b" integrity sha512-W25S1UUm9Lm9VnE0TvCzL7aso/NCzDEaXLaElCUO/KaVitw0+IBicSVfM1L1c0YHK5TOFh73yQ2naCpVHEQ/OQ== From 0058a02dbf140a5b4b1c7ecc4462bc5e686d29e4 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Tue, 24 Aug 2021 23:08:13 -0700 Subject: [PATCH 16/42] Add support for more types of dependencies in SVG (#6750) --- packages/core/integration-tests/test/css.js | 2 +- packages/core/integration-tests/test/html.js | 2 +- .../test/integration/svg/circle.svg | 8 ++ .../test/integration/svg/gradient.svg | 8 ++ .../test/integration/svg/module.js | 2 + .../test/integration/svg/path.svg | 6 ++ .../test/integration/svg/script.js | 1 + .../core/integration-tests/test/javascript.js | 2 +- packages/core/integration-tests/test/svg.js | 57 ++++++++++++ packages/transformers/svg/src/dependencies.js | 90 ++++++++++++++++++- .../svg/test/parseFuncIRI.test.js | 24 +++++ 11 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/svg/gradient.svg create mode 100644 packages/core/integration-tests/test/integration/svg/module.js create mode 100644 packages/core/integration-tests/test/integration/svg/path.svg create mode 100644 packages/core/integration-tests/test/integration/svg/script.js create mode 100644 packages/transformers/svg/test/parseFuncIRI.test.js diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index 766590d9439..d14513c48ff 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -319,7 +319,7 @@ describe('css', () => { assert.equal( css.trim(), `.svg-img { - background-image: url('data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%27120%27%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%2F%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%23blur-_.%21~%2a%29%22%20%2F%3E%0A%3C%2Fsvg%3E%0A'); + background-image: url('data:image/svg+xml,%3Csvg%20width%3D%22120%22%20height%3D%22120%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%0A%20%20%3Cfilter%20id%3D%22blur-_.%21~%2a%22%3E%0A%20%20%20%20%3CfeGaussianBlur%20stdDeviation%3D%225%22%3E%3C%2FfeGaussianBlur%3E%0A%20%20%3C%2Ffilter%3E%0A%20%20%3Ccircle%20cx%3D%2260%22%20cy%3D%2260%22%20r%3D%2250%22%20fill%3D%22green%22%20filter%3D%22url%28%27%23blur-_.%21~%2a%27%29%22%3E%3C%2Fcircle%3E%0A%3C%2Fsvg%3E%0A'); }`, ); }); diff --git a/packages/core/integration-tests/test/html.js b/packages/core/integration-tests/test/html.js index 3cb53488031..990a8344088 100644 --- a/packages/core/integration-tests/test/html.js +++ b/packages/core/integration-tests/test/html.js @@ -2442,7 +2442,7 @@ describe('html', function() { ); assert.equal( contents.trim(), - ``, + ``, ); }); diff --git a/packages/core/integration-tests/test/integration/svg/circle.svg b/packages/core/integration-tests/test/integration/svg/circle.svg index cd0514173c6..9a99def24bb 100644 --- a/packages/core/integration-tests/test/integration/svg/circle.svg +++ b/packages/core/integration-tests/test/integration/svg/circle.svg @@ -5,4 +5,12 @@ + + + + Quick brown fox jumps over the lazy dog. + + + diff --git a/packages/core/integration-tests/test/integration/svg/module.js b/packages/core/integration-tests/test/integration/svg/module.js index 367580709de..61f90cdfb52 100644 --- a/packages/core/integration-tests/test/integration/svg/module.js +++ b/packages/core/integration-tests/test/integration/svg/module.js @@ -1,2 +1,3 @@ +import './style.css'; import './script'; console.log('module'); diff --git a/packages/core/integration-tests/test/integration/svg/style.css b/packages/core/integration-tests/test/integration/svg/style.css new file mode 100644 index 00000000000..cb771a383a0 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg/style.css @@ -0,0 +1,3 @@ +circle { + fill: red; +} diff --git a/packages/core/integration-tests/test/svg.js b/packages/core/integration-tests/test/svg.js index 308e88c4995..302a26a1f9c 100644 --- a/packages/core/integration-tests/test/svg.js +++ b/packages/core/integration-tests/test/svg.js @@ -39,6 +39,10 @@ describe('svg', function() { type: 'js', assets: ['module.js', 'script.js'], }, + { + type: 'css', + assets: ['style.css'], + }, ]); let file = await outputFS.readFile( @@ -81,6 +85,13 @@ describe('svg', function() { )}"`, ), ); + assert( + file.includes( + ` b.type === 'css').filePath, + )}"?>`, + ), + ); }); it('should minify SVG bundles', async function() { @@ -154,16 +165,38 @@ describe('svg', function() { type: 'css', assets: ['img.svg', 'test.css'], }, + { + type: 'css', + assets: ['img.svg'], + }, { name: 'img.svg', assets: ['img.svg'], }, + { + type: 'svg', + assets: ['gradient.svg'], + }, + { + type: 'js', + assets: ['img.svg', 'script.js'], + }, ]); const svg = await outputFS.readFile(path.join(distDir, 'img.svg'), 'utf8'); assert(!svg.includes('@import')); assert(svg.includes(':root {\n fill: red\n}')); + assert( + svg.includes( + `"fill: url(${path.basename( + b.getBundles().find(b => b.name.startsWith('gradient')).filePath, + )}#myGradient)"`, + ), + ); + assert(svg.includes('