Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix postcss modules composes imports #2642

Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
194 changes: 192 additions & 2 deletions packages/core/integration-tests/test/css.js
Expand Up @@ -289,9 +289,9 @@ describe('css', function() {
assert.equal(typeof output, 'function');

let value = output();
assert(/_index_[0-9a-z]+_1/.test(value));
assert(/_index_[0-9a-z]/.test(value));

let cssClass = value.match(/(_index_[0-9a-z]+_1)/)[1];
let cssClass = value.match(/(_index_[0-9a-z]+)/)[1];

let css = await fs.readFile(
path.join(__dirname, '/dist/index.css'),
Expand All @@ -313,6 +313,196 @@ describe('css', function() {
assert.equal(run1(), run2());
});

it('should support postcss composes imports', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index.js')
);

await assertBundleTree(b, {
name: 'index.js',
assets: ['index.js', 'composes-1.css', 'composes-2.css', 'mixins.css'],
childBundles: [
{
name: 'index.css',
assets: ['composes-1.css', 'composes-2.css', 'mixins.css'],
childBundles: []
},
{
type: 'map'
}
]
});

let output = await run(b);
assert.equal(typeof output, 'function');

let value = output();
assert.equal(value.composes1, '_composes1_29315 _test_19e21');
assert.equal(value.composes2, '_composes2_b5878 _test_19e21');

let css = await fs.readFile(
path.join(__dirname, '/dist/index.css'),
'utf8'
);
let cssClass1 = value.composes1.match(/(_composes1_[0-9a-z]+)/)[1];
assert(css.includes(`.${cssClass1}`));
let cssClass2 = value.composes2.match(/(_composes2_[0-9a-z]+)/)[1];
assert(css.includes(`.${cssClass2}`));
});

it('should not include css twice for postcss composes imports', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index.js')
);

await run(b);

let css = await fs.readFile(
path.join(__dirname, '/dist/index.css'),
'utf8'
);
assert.equal(
css.indexOf('height: 100px;'),
css.lastIndexOf('height: 100px;')
);
});

it('should support postcss composes imports for sass', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index2.js')
);

await assertBundleTree(b, {
name: 'index2.js',
assets: ['index2.js', 'composes-3.css', 'mixins.scss'],
childBundles: [
{
name: 'index2.css',
assets: ['composes-3.css', 'mixins.scss'],
childBundles: []
},
{
type: 'map'
}
]
});

let output = await run(b);
assert.equal(typeof output, 'function');

let value = output();
assert.equal(value.composes3, '_composes3_6834d _test_c0a12');

let css = await fs.readFile(
path.join(__dirname, '/dist/index2.css'),
'utf8'
);
assert(css.includes('height: 200px;'));
});

it('should support postcss composes imports with custom path names', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index3.js')
);

await assertBundleTree(b, {
name: 'index3.js',
assets: ['index3.js', 'composes-4.css', 'mixins.css'],
childBundles: [
{
name: 'index3.css',
assets: ['composes-4.css', 'mixins.css'],
childBundles: []
},
{
type: 'map'
}
]
});

let output = await run(b);
assert.equal(typeof output, 'function');

let value = output();
assert.equal(value.composes4, '_composes4_7038c _test_19e21');

let css = await fs.readFile(
path.join(__dirname, '/dist/index3.css'),
'utf8'
);
assert(css.includes('height: 100px;'));
});

it('should support deep nested postcss composes imports', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index4.js')
);

await assertBundleTree(b, {
name: 'index4.js',
assets: [
'index4.js',
'composes-5.css',
'mixins-intermediate.css',
'mixins.css'
],
childBundles: [
{
name: 'index4.css',
assets: ['composes-5.css', 'mixins-intermediate.css', 'mixins.css'],
childBundles: []
},
{
type: 'map'
}
]
});

let output = await run(b);
assert.equal(typeof output, 'function');

let value = output();
assert.equal(
value.composes5,
'_composes5_c6088 _intermediate_6b681 _test_19e21'
);

let css = await fs.readFile(
path.join(__dirname, '/dist/index4.css'),
'utf8'
);
assert(css.includes('height: 100px;'));
assert(css.includes('height: 300px;'));
assert(css.indexOf('_test_19e21') < css.indexOf('_intermediate_6b681'));
});

it('should support postcss composes imports for multiple selectors', async function() {
let b = await bundle(
path.join(__dirname, '/integration/postcss-composes/index5.js')
);

await assertBundleTree(b, {
name: 'index5.js',
assets: ['index5.js', 'composes-6.css', 'mixins.css'],
childBundles: [
{
name: 'index5.css',
assets: ['composes-6.css', 'mixins.css'],
childBundles: []
},
{
type: 'map'
}
]
});

let output = await run(b);
assert.equal(typeof output, 'function');

let value = output();
assert.equal(value.composes6, '_composes6_d20ad _test_19e21 _test-2_19e21');
});

it('should minify CSS in production mode', async function() {
let b = await bundle(
path.join(__dirname, '/integration/cssnano/index.js'),
Expand Down
@@ -0,0 +1,3 @@
{
"modules": true
}
@@ -0,0 +1,4 @@
.composes1 {
composes: test from './mixins.css';
border: 3px solid orange;
}
@@ -0,0 +1,4 @@
.composes2 {
composes: test from './mixins.css';
border: 3px solid red;
}
@@ -0,0 +1,4 @@
.composes3 {
composes: test from './mixins.scss';
border: 3px solid brown;
}
@@ -0,0 +1,4 @@
.composes4 {
composes: test from '~mixins.css';
border: 3px solid black;
}
@@ -0,0 +1,4 @@
.composes5 {
composes: intermediate from './mixins-intermediate.css';
border: 3px solid yellow;
}
@@ -0,0 +1,4 @@
.composes6 {
composes: test test-2 from './mixins.css';
border: 3px solid orangered;
}
@@ -0,0 +1,6 @@
var map1 = require('./composes-1.css');
var map2 = require('./composes-2.css');

module.exports = function () {
return Object.assign({}, map1, map2);
};
@@ -0,0 +1,5 @@
var map3 = require('./composes-3.css');

module.exports = function () {
return map3;
};
@@ -0,0 +1,5 @@
var map4 = require('./composes-4.css');

module.exports = function () {
return map4;
};
@@ -0,0 +1,5 @@
var map5 = require('./composes-5.css');

module.exports = function () {
return map5;
};
@@ -0,0 +1,5 @@
var map6 = require('./composes-6.css');

module.exports = function () {
return map6;
};
@@ -0,0 +1,4 @@
.intermediate {
composes: test from './mixins.css';
height: 300px;
}
@@ -0,0 +1,8 @@
.test {
height: 100px;
width: 100px;
}

.test-2 {
background: red;
}
@@ -0,0 +1,6 @@
$test: 200px;

.test {
height: $test;
width: $test;
}
4 changes: 2 additions & 2 deletions packages/core/integration-tests/test/less.js
Expand Up @@ -198,12 +198,12 @@ describe('less', function() {

let output = await run(b);
assert.equal(typeof output, 'function');
assert.equal(output(), '_index_ku5n8_1');
assert.equal(output(), '_index_394ba');

let css = await fs.readFile(
path.join(__dirname, '/dist/index.css'),
'utf8'
);
assert(css.includes('._index_ku5n8_1'));
assert(css.includes('._index_394ba'));
});
});
4 changes: 2 additions & 2 deletions packages/core/integration-tests/test/stylus.js
Expand Up @@ -139,13 +139,13 @@ describe('stylus', function() {

let output = await run(b);
assert.equal(typeof output, 'function');
assert.equal(output(), '_index_g9mqo_1');
assert.equal(output(), '_index_6768d');

let css = await fs.readFile(
path.join(__dirname, '/dist/index.css'),
'utf8'
);
assert(css.includes('._index_g9mqo_1'));
assert(css.includes('._index_6768d'));
});

it('should support requiring stylus files with glob dependencies', async function() {
Expand Down
1 change: 1 addition & 0 deletions packages/core/parcel-bundler/package.json
Expand Up @@ -41,6 +41,7 @@
"command-exists": "^1.2.6",
"commander": "^2.11.0",
"cross-spawn": "^6.0.4",
"css-modules-loader-core": "^1.1.0",
"cssnano": "^4.0.0",
"deasync": "^0.1.14",
"dotenv": "^5.0.0",
Expand Down
27 changes: 17 additions & 10 deletions packages/core/parcel-bundler/src/Asset.js
Expand Up @@ -84,16 +84,7 @@ class Asset {
this.dependencies.set(name, Object.assign({name}, opts));
}

addURLDependency(url, from = this.name, opts) {
if (!url || isURL(url)) {
return url;
}

if (typeof from === 'object') {
opts = from;
from = this.name;
}

resolveDependency(url, from = this.name) {
const parsed = URL.parse(url);
let depName;
let resolved;
Expand All @@ -110,8 +101,24 @@ class Asset {
depName = './' + path.relative(path.dirname(this.name), resolved);
}

return {depName, resolved};
}

addURLDependency(url, from = this.name, opts) {
if (!url || isURL(url)) {
return url;
}

if (typeof from === 'object') {
opts = from;
from = this.name;
}

const {depName, resolved} = this.resolveDependency(url, from);

this.addDependency(depName, Object.assign({dynamic: true, resolved}, opts));

const parsed = URL.parse(url);
parsed.pathname = this.options.parser
.getAsset(resolved, this.options)
.generateBundleName();
Expand Down