From b1165bf08b30314d511df6497f5dbd711ad778df Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Thu, 7 Mar 2019 23:22:52 +0100 Subject: [PATCH 1/5] Correctly build URLs for CSS Fix real core issue of #2518 --- packages/core/integration-tests/test/css.js | 6 +----- packages/core/parcel-bundler/src/Asset.js | 3 +-- packages/core/parcel-bundler/src/assets/CSSAsset.js | 5 +++++ 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index d55db7e807f..1604ac2930d 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -282,11 +282,7 @@ describe('css', function() { assert( await fs.exists( - path.join( - __dirname, - path.dirname('/dist/a/style1.css'), - css.match(/url\(([^)]*)\)/)[1] - ) + path.join(__dirname, 'dist', css.match(/url\(([^)]*)\)/)[1]) ), 'path specified in url() exists' ); diff --git a/packages/core/parcel-bundler/src/Asset.js b/packages/core/parcel-bundler/src/Asset.js index 381d6e9f817..be7999cfda4 100644 --- a/packages/core/parcel-bundler/src/Asset.js +++ b/packages/core/parcel-bundler/src/Asset.js @@ -257,8 +257,7 @@ class Asset { // Replace temporary bundle names in the output with the final content-hashed names. let newValue = value; for (let [name, map] of bundleNameMap) { - let mapRelative = path.relative(path.dirname(this.relativeName), map); - newValue = newValue.split(name).join(mapRelative); + newValue = newValue.split(name).join(map); } // Copy `this.generated` on write so we don't end up writing the final names to the cache. diff --git a/packages/core/parcel-bundler/src/assets/CSSAsset.js b/packages/core/parcel-bundler/src/assets/CSSAsset.js index 967457c82f9..dcae9a47840 100644 --- a/packages/core/parcel-bundler/src/assets/CSSAsset.js +++ b/packages/core/parcel-bundler/src/assets/CSSAsset.js @@ -6,6 +6,8 @@ const CssSyntaxError = require('postcss/lib/css-syntax-error'); const SourceMap = require('../SourceMap'); const loadSourceMap = require('../utils/loadSourceMap'); const path = require('path'); +const urlJoin = require('../utils/urlJoin'); +const isURL = require('../utils/is-url'); const URL_RE = /url\s*\("?(?![a-z]+:)/; const IMPORT_RE = /@import/; @@ -91,6 +93,9 @@ class CSSAsset extends Asset { let url = this.addURLDependency(node.nodes[0].value, { loc: decl.source.start }); + if (!isURL(url)) { + url = urlJoin(this.options.publicURL, url); + } dirty = node.nodes[0].value !== url; node.nodes[0].value = url; } From 4e0024f59d9e28c44a04c6efd0b7abbd57a44548 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig Date: Fri, 8 Mar 2019 21:58:11 +0100 Subject: [PATCH 2/5] Fix tests --- packages/core/integration-tests/test/css.js | 11 +++++++---- packages/core/integration-tests/test/sass.js | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index 1604ac2930d..5ecac7f9688 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -166,7 +166,7 @@ describe('css', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); + assert(/url\("\/test\.[0-9a-f]+\.woff2"\)/.test(css)); assert(css.includes('url("http://google.com")')); assert(css.includes('.index')); assert(css.includes('url("data:image/gif;base64,quotes")')); @@ -179,7 +179,7 @@ describe('css', function() { path.join( __dirname, '/dist/', - css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1] + css.match(/url\("(\/test\.[0-9a-f]+\.woff2)"\)/)[1] ) ) ); @@ -225,7 +225,10 @@ describe('css', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert(/url\(test\.[0-9a-f]+\.woff2\)/.test(css), 'woff ext found in css'); + assert( + /url\(\/test\.[0-9a-f]+\.woff2\)/.test(css), + 'woff ext found in css' + ); assert(css.includes('url(http://google.com)'), 'url() found'); assert(css.includes('.index'), '.index found'); assert(css.includes('url("data:image/gif;base64,quotes")')); @@ -238,7 +241,7 @@ describe('css', function() { path.join( __dirname, '/dist/', - css.match(/url\((test\.[0-9a-f]+\.woff2)\)/)[1] + css.match(/url\((\/test\.[0-9a-f]+\.woff2)\)/)[1] ) ) ); diff --git a/packages/core/integration-tests/test/sass.js b/packages/core/integration-tests/test/sass.js index 9640bd3a329..5d6a4ad304c 100644 --- a/packages/core/integration-tests/test/sass.js +++ b/packages/core/integration-tests/test/sass.js @@ -188,7 +188,7 @@ describe('sass', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); + assert(/url\("\/test\.[0-9a-f]+\.woff2"\)/.test(css)); assert(css.includes('url("http://google.com")')); assert(css.includes('.index')); @@ -197,7 +197,7 @@ describe('sass', function() { path.join( __dirname, '/dist/', - css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1] + css.match(/url\("(\/test\.[0-9a-f]+\.woff2)"\)/)[1] ) ) ); From 026a8c90c67b4aeea52c23a60d3dabedfa53fe2e Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 11 Mar 2019 10:53:34 -0700 Subject: [PATCH 3/5] Return relative path from addURLDependency --- packages/core/integration-tests/test/css.js | 19 +++++++------------ packages/core/integration-tests/test/sass.js | 4 ++-- packages/core/parcel-bundler/src/Asset.js | 5 +++-- .../parcel-bundler/src/assets/CSSAsset.js | 5 ----- 4 files changed, 12 insertions(+), 21 deletions(-) diff --git a/packages/core/integration-tests/test/css.js b/packages/core/integration-tests/test/css.js index 5ecac7f9688..16e9101edd1 100644 --- a/packages/core/integration-tests/test/css.js +++ b/packages/core/integration-tests/test/css.js @@ -166,7 +166,7 @@ describe('css', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert(/url\("\/test\.[0-9a-f]+\.woff2"\)/.test(css)); + assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); assert(css.includes('url("http://google.com")')); assert(css.includes('.index')); assert(css.includes('url("data:image/gif;base64,quotes")')); @@ -179,7 +179,7 @@ describe('css', function() { path.join( __dirname, '/dist/', - css.match(/url\("(\/test\.[0-9a-f]+\.woff2)"\)/)[1] + css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1] ) ) ); @@ -225,10 +225,7 @@ describe('css', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert( - /url\(\/test\.[0-9a-f]+\.woff2\)/.test(css), - 'woff ext found in css' - ); + assert(/url\(test\.[0-9a-f]+\.woff2\)/.test(css), 'woff ext found in css'); assert(css.includes('url(http://google.com)'), 'url() found'); assert(css.includes('.index'), '.index found'); assert(css.includes('url("data:image/gif;base64,quotes")')); @@ -241,7 +238,7 @@ describe('css', function() { path.join( __dirname, '/dist/', - css.match(/url\((\/test\.[0-9a-f]+\.woff2)\)/)[1] + css.match(/url\((test\.[0-9a-f]+\.woff2)\)/)[1] ) ) ); @@ -275,17 +272,15 @@ describe('css', function() { } ]); - let css = await fs.readFile( - path.join(__dirname, '/dist/a/style1.css'), - 'utf8' - ); + let cssPath = path.join(__dirname, '/dist/a/style1.css'); + let css = await fs.readFile(cssPath, 'utf8'); assert(css.includes('background-image'), 'includes `background-image`'); assert(/url\([^)]*\)/.test(css), 'includes url()'); assert( await fs.exists( - path.join(__dirname, 'dist', css.match(/url\(([^)]*)\)/)[1]) + path.join(path.dirname(cssPath), css.match(/url\(([^)]*)\)/)[1]) ), 'path specified in url() exists' ); diff --git a/packages/core/integration-tests/test/sass.js b/packages/core/integration-tests/test/sass.js index 5d6a4ad304c..9640bd3a329 100644 --- a/packages/core/integration-tests/test/sass.js +++ b/packages/core/integration-tests/test/sass.js @@ -188,7 +188,7 @@ describe('sass', function() { path.join(__dirname, '/dist/index.css'), 'utf8' ); - assert(/url\("\/test\.[0-9a-f]+\.woff2"\)/.test(css)); + assert(/url\("test\.[0-9a-f]+\.woff2"\)/.test(css)); assert(css.includes('url("http://google.com")')); assert(css.includes('.index')); @@ -197,7 +197,7 @@ describe('sass', function() { path.join( __dirname, '/dist/', - css.match(/url\("(\/test\.[0-9a-f]+\.woff2)"\)/)[1] + css.match(/url\("(test\.[0-9a-f]+\.woff2)"\)/)[1] ) ) ); diff --git a/packages/core/parcel-bundler/src/Asset.js b/packages/core/parcel-bundler/src/Asset.js index be7999cfda4..3649528d5cf 100644 --- a/packages/core/parcel-bundler/src/Asset.js +++ b/packages/core/parcel-bundler/src/Asset.js @@ -119,11 +119,12 @@ class Asset { this.addDependency(depName, Object.assign({dynamic: true, resolved}, opts)); - const parsed = URL.parse(url); - parsed.pathname = this.options.parser + let parsed = URL.parse(url); + let name = this.options.parser .getAsset(resolved, this.options) .generateBundleName(); + parsed.pathname = path.relative(path.dirname(this.relativeName), name); return URL.format(parsed); } diff --git a/packages/core/parcel-bundler/src/assets/CSSAsset.js b/packages/core/parcel-bundler/src/assets/CSSAsset.js index dcae9a47840..967457c82f9 100644 --- a/packages/core/parcel-bundler/src/assets/CSSAsset.js +++ b/packages/core/parcel-bundler/src/assets/CSSAsset.js @@ -6,8 +6,6 @@ const CssSyntaxError = require('postcss/lib/css-syntax-error'); const SourceMap = require('../SourceMap'); const loadSourceMap = require('../utils/loadSourceMap'); const path = require('path'); -const urlJoin = require('../utils/urlJoin'); -const isURL = require('../utils/is-url'); const URL_RE = /url\s*\("?(?![a-z]+:)/; const IMPORT_RE = /@import/; @@ -93,9 +91,6 @@ class CSSAsset extends Asset { let url = this.addURLDependency(node.nodes[0].value, { loc: decl.source.start }); - if (!isURL(url)) { - url = urlJoin(this.options.publicURL, url); - } dirty = node.nodes[0].value !== url; node.nodes[0].value = url; } From 04de0706cf0e77120bd6ef4684a7d7ad8c3fc4fd Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 11 Mar 2019 10:54:10 -0700 Subject: [PATCH 4/5] Add test for import a url to a raw asset in a subfolder --- .../import-raw-subfolder/foo/test.txt | 1 + .../integration/import-raw-subfolder/index.js | 5 ++++ .../core/integration-tests/test/javascript.js | 26 +++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 packages/core/integration-tests/test/integration/import-raw-subfolder/foo/test.txt create mode 100644 packages/core/integration-tests/test/integration/import-raw-subfolder/index.js diff --git a/packages/core/integration-tests/test/integration/import-raw-subfolder/foo/test.txt b/packages/core/integration-tests/test/integration/import-raw-subfolder/foo/test.txt new file mode 100644 index 00000000000..37d4e6c5c48 --- /dev/null +++ b/packages/core/integration-tests/test/integration/import-raw-subfolder/foo/test.txt @@ -0,0 +1 @@ +hi there diff --git a/packages/core/integration-tests/test/integration/import-raw-subfolder/index.js b/packages/core/integration-tests/test/integration/import-raw-subfolder/index.js new file mode 100644 index 00000000000..8f707b51be4 --- /dev/null +++ b/packages/core/integration-tests/test/integration/import-raw-subfolder/index.js @@ -0,0 +1,5 @@ +const url = require('./foo/test.txt'); + +module.exports = function () { + return url; +}; diff --git a/packages/core/integration-tests/test/javascript.js b/packages/core/integration-tests/test/javascript.js index a52f63d62ef..5f930d61ac9 100644 --- a/packages/core/integration-tests/test/javascript.js +++ b/packages/core/integration-tests/test/javascript.js @@ -795,6 +795,32 @@ describe('javascript', function() { assert(await fs.exists(path.join(__dirname, '/dist/', output()))); }); + it('should support importing a URL to a raw asset in a subfolder', async function() { + let b = await bundle( + path.join(__dirname, '/integration/import-raw-subfolder/index.js') + ); + + await assertBundleTree(b, { + name: 'index.js', + assets: ['index.js', 'test.txt'], + childBundles: [ + { + type: 'map' + }, + { + type: 'txt', + assets: ['test.txt'], + childBundles: [] + } + ] + }); + + let output = await run(b); + assert.equal(typeof output, 'function'); + assert(/^\/test\.[0-9a-f]+\.txt$/.test(output())); + assert(await fs.exists(path.join(__dirname, '/dist/', output()))); + }); + it('should minify JS in production mode', async function() { let b = await bundle(path.join(__dirname, '/integration/uglify/index.js'), { production: true From 477b1a3f506d0300bb4072f08421726dc38c78d6 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 11 Mar 2019 11:23:43 -0700 Subject: [PATCH 5/5] Fix test --- packages/core/parcel-bundler/test/asset.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/core/parcel-bundler/test/asset.js b/packages/core/parcel-bundler/test/asset.js index a093f469493..b6add8b2f4b 100644 --- a/packages/core/parcel-bundler/test/asset.js +++ b/packages/core/parcel-bundler/test/asset.js @@ -48,7 +48,7 @@ describe('Asset', () => { } } }; - const asset = new Asset('test', options); + const asset = new Asset('/root/dir/test', options); it('should ignore urls', () => { const url = 'https://parceljs.org/assets.html'; @@ -63,6 +63,11 @@ describe('Asset', () => { assert.strictEqual(asset.addURLDependency('foo'), bundleName); }); + it('should generate relative path', () => { + const asset = new Asset('/root/dir/test/baz', options); + assert.strictEqual(asset.addURLDependency('foo'), '../' + bundleName); + }); + it('should preserve query and hash', () => { assert.strictEqual( asset.addURLDependency('foo#bar'),