Skip to content

Commit

Permalink
feat: add support for locally scoped css (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Apr 8, 2017
1 parent 8e15bd4 commit 5e8d0b5
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 16 deletions.
45 changes: 32 additions & 13 deletions lib/index.js
Expand Up @@ -7,7 +7,6 @@ const CssHandler = require('./handlers/css-handler')

const MANDATORY_BLACKLIST = [
/^webpack\/bootstrap/,
'/css-loader/index.js',
'/css-loader/lib/css-base.js',
'/style-loader/addStyles.js',
]
Expand All @@ -34,20 +33,40 @@ class NukeCssPlugin {
})
}

static gatherSourceContent(options, assets) {
static determineJsContent(node) {
const source = node.source
const content = node.originalSource

if (source.includes('/css-loader/index.js') && !content.includes('removed by extract-text')) {
const indexOfLocals = content.indexOf('exports.locals')
return indexOfLocals >= 0 ? content.slice(indexOfLocals) : ''
} else {
return content
}
}

static gatherJsSourceContent(blacklist, asset) {
return asset.listMap({}).children
.map(node => {
if (!node.source) {
return false
} else if (blacklist.find(pattern => pattern.test(node.source))) {
return false
}

return {
type: 'js',
content: NukeCssPlugin.determineJsContent(node),
}
})
.filter(item => item && item.content)
}

static gatherAllSourceContent(options, assets) {
const blacklist = NukeCssPlugin.getBlacklist(options)
return _(assets)
.filter(item => item.type === 'js')
.map(({asset, type}) => {
return asset.listMap({}).children
.filter(node => {
const doesNotMatch = pattern => !pattern.test(node.source)
return node.source && _.every(blacklist, doesNotMatch)
})
.map(node => {
return {type, content: node.originalSource}
})
})
.map(item => NukeCssPlugin.gatherJsSourceContent(blacklist, item.asset))
.flatten()
.concat(options.sources)
.value()
Expand All @@ -59,7 +78,7 @@ class NukeCssPlugin {
return {asset, name, type}
})

const sourceContent = NukeCssPlugin.gatherSourceContent(this._options, assets)
const sourceContent = NukeCssPlugin.gatherAllSourceContent(this._options, assets)
assets.forEach(({asset, name, type}) => {
try {
const handler = this._handlers[type]
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/entry.css
Expand Up @@ -28,3 +28,7 @@
.fa-blacklisted {
content: 'fa';
}

:local .my-local-class :global .fa-table {
content: 'locally scoped';
}
4 changes: 4 additions & 0 deletions test/fixtures/entry.extracted.css
Expand Up @@ -44,3 +44,7 @@ a:hover {
.html-ignored {
color: white;
}

:local .my-other-local-class :global .fa-table {
content: 'locally scoped';
}
4 changes: 2 additions & 2 deletions test/fixtures/entry.js
@@ -1,10 +1,10 @@
const data = require('./entry.css')
require('./entry.extracted.css')
const data2 = require('./entry.extracted.css')
const myIcons = {
'fa-address-book-o': true,
'fa': true,
'fa-save': true,
'fa-table': true,
}

console.log(data, myIcons)
console.log(data, data2, myIcons)
7 changes: 6 additions & 1 deletion test/index.test.js
Expand Up @@ -36,7 +36,7 @@ describe('NukeCssPlugin', () => {
function findLineAndColumn(css, string) {
const lines = css.split('\n')
const line = lines.findIndex(l => l.includes(string)) + 1
if (line === -1) {
if (line === -1 || !lines[line - 1]) {
throw new Error(`could not find string ${string}`)
}

Expand All @@ -59,6 +59,11 @@ describe('NukeCssPlugin', () => {
expect(fileStats['out.css'].content).to.not.contain('.my-favorite-class')
})

it('should work with locally scoped', () => {
expect(fileStats['out.js'].content).to.contain('locally scoped')
expect(fileStats['out.css'].content).to.contain('locally scoped')
})

it('should generate a source map', () => {
expect(fileStats).to.have.property('out.css.map')

Expand Down

0 comments on commit 5e8d0b5

Please sign in to comment.