Skip to content

Commit

Permalink
feat: allow multiple entry files and outputs (#264)
Browse files Browse the repository at this point in the history
Bundle multiple bundles for multiple input entries.
  • Loading branch information
chmelevskij authored Apr 23, 2020
1 parent b27c3eb commit 3ea986c
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 143 deletions.
114 changes: 76 additions & 38 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,30 +128,60 @@ export default (options = {}) => {
!(options_.dir || options_.file)
) return

const entries = Object
.values(bundle)
.filter(bundle => bundle.isEntry)
const isMultiEntry = entries.length > 1

let concat
// TODO: support `[hash]`
const dir = options_.dir || path.dirname(options_.file)
const file =
options_.file ||
path.join(
options_.dir,
Object.keys(bundle).find(fileName => bundle[fileName].isEntry)
)
const getExtracted = () => {
let fileName = `${path.basename(file, path.extname(file))}.css`
const getExtracted = ({ fileName: entryFileName, modules }) => {
let baseName
let fileName
let dir

if (isMultiEntry) {
baseName = `${path.basename(entryFileName, path.extname(entryFileName))}.css`
dir = path.dirname(entryFileName)
fileName = path.join(
dir,
baseName
)
} else {
// TODO: copy from the previous version, refactor
dir = options_.dir || path.dirname(options_.file)
const file = options_.file || path.join(
options_.dir,
Object.keys(bundle).find(fileName => bundle[fileName].isEntry)
)
fileName = `${path.basename(file, path.extname(file))}.css`
baseName = fileName
}

if (typeof postcssLoaderOptions.extract === 'string') {
if (path.isAbsolute(postcssLoaderOptions.extract)) {
const dir = options_.dir || path.dirname(options_.file)
fileName = normalizePath(path.relative(dir, postcssLoaderOptions.extract))
} else {
fileName = normalizePath(postcssLoaderOptions.extract)
}

baseName = fileName
concat = concat || new Concat(true, fileName, '\n')
} else {
concat = new Concat(true, fileName, '\n')
}

const concat = new Concat(true, fileName, '\n')
const entries = [...extracted.values()]
const { modules } = bundle[normalizePath(path.relative(dir, file))]
const entries = []

if (modules) {
const fileList = Object.keys(modules)
const moduleIds = [...this.moduleIds]
fileList.forEach(id => {
if (extracted.has(id)) {
entries.push(extracted.get(id))
}
})
entries.sort(
(a, b) => moduleIds.indexOf(a.id) - moduleIds.indexOf(b.id)
)
Expand All @@ -161,7 +191,7 @@ export default (options = {}) => {
const relative = normalizePath(path.relative(dir, result.id))
const map = result.map || null
if (map) {
map.file = fileName
map.file = baseName
}

concat.add(relative, result.code, map)
Expand All @@ -175,7 +205,7 @@ export default (options = {}) => {
'utf8'
).toString('base64')}*/`
} else if (sourceMap === true) {
code += `\n/*# sourceMappingURL=${fileName}.map */`
code += `\n/*# sourceMappingURL=${baseName}.map */`
}

return {
Expand All @@ -193,38 +223,46 @@ export default (options = {}) => {
}
}

let { code, codeFileName, map, mapFileName } = getExtracted()
// Perform cssnano on the extracted file
if (postcssLoaderOptions.minimize) {
const cssOptions = postcssLoaderOptions.minimize
cssOptions.from = codeFileName
if (sourceMap === 'inline') {
cssOptions.map = { inline: true }
} else if (sourceMap === true && map) {
cssOptions.map = { prev: map }
cssOptions.to = codeFileName
}
const handleEntry = async entry => {
let { code, codeFileName, map, mapFileName } = getExtracted(entry)
// Perform cssnano on the extracted file
if (postcssLoaderOptions.minimize) {
const cssOptions = postcssLoaderOptions.minimize
cssOptions.from = codeFileName
if (sourceMap === 'inline') {
cssOptions.map = { inline: true }
} else if (sourceMap === true && map) {
cssOptions.map = { prev: map }
cssOptions.to = codeFileName
}

const result = await require('cssnano').process(code, cssOptions)
code = result.css
const result = await require('cssnano').process(code, cssOptions)
code = result.css

if (sourceMap === true && result.map && result.map.toString) {
map = result.map.toString()
if (sourceMap === true && result.map && result.map.toString) {
map = result.map.toString()
}
}
}

this.emitFile({
fileName: codeFileName,
type: 'asset',
source: code
})
if (map) {
this.emitFile({
fileName: mapFileName,
fileName: codeFileName,
type: 'asset',
source: map
source: code
})
if (map) {
this.emitFile({
fileName: mapFileName,
type: 'asset',
source: map
})
}
}

await Promise.all(
Object.values(bundle)
.filter(bundle => bundle.isEntry)
.map(handleEntry)
)
}
}
}
144 changes: 49 additions & 95 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,10 @@ exports[`extract custom-path: css code 1`] = `
color: red;
}
body {
color: #f00;
background: #f00;
}
/*# sourceMappingURL=test/fixtures/simple/style.css.map */
#sidebar {
width: 30%;
background-color: #faa; }
#header {
color: #6c94be;
}
.pcss {
color: red;
}
/*# sourceMappingURL=this/is/extracted.css.map */"
`;

exports[`extract custom-path: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\",\\"test/fixtures/simple/style.styl\\",\\"style.styl\\",\\"style.sass\\",\\"test/fixtures/simple/style.less\\",\\"style.less\\",\\"style.pcss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ;;ACFA;EACE,WAAO;EACP,gBAAY;ACCd;AACA,yDAAyD;ACJzD;EACE,UAAU;EACV,sBAAsB,EAAE;;ACC1B;EACE,cAAA;ACFF;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"this/is/extracted.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\",null,null,\\"#sidebar {\\\\n width: 30%;\\\\n background-color: #faa; }\\\\n\\",null,null,\\".pcss {\\\\n color: red;\\\\n}\\\\n\\"]}"`;
exports[`extract custom-path: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"this/is/extracted.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\"]}"`;

exports[`extract custom-path: js code 1`] = `
"'use strict';
Expand All @@ -204,27 +187,10 @@ exports[`extract relative-path: css code 1`] = `
color: red;
}
body {
color: #f00;
background: #f00;
}
/*# sourceMappingURL=test/fixtures/simple/style.css.map */
#sidebar {
width: 30%;
background-color: #faa; }
#header {
color: #6c94be;
}
.pcss {
color: red;
}
/*# sourceMappingURL=this/is/extracted.css.map */"
`;

exports[`extract relative-path: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\",\\"test/fixtures/simple/style.styl\\",\\"style.styl\\",\\"style.sass\\",\\"test/fixtures/simple/style.less\\",\\"style.less\\",\\"style.pcss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ;;ACFA;EACE,WAAO;EACP,gBAAY;ACCd;AACA,yDAAyD;ACJzD;EACE,UAAU;EACV,sBAAsB,EAAE;;ACC1B;EACE,cAAA;ACFF;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"this/is/extracted.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\",null,null,\\"#sidebar {\\\\n width: 30%;\\\\n background-color: #faa; }\\\\n\\",null,null,\\".pcss {\\\\n color: red;\\\\n}\\\\n\\"]}"`;
exports[`extract relative-path: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"this/is/extracted.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\"]}"`;

exports[`extract relative-path: js code 1`] = `
"'use strict';
Expand All @@ -242,25 +208,7 @@ exports[`extract sourcemap-inline: css code 1`] = `
color: red;
}
body {
color: #f00;
background: #f00;
}
/*# sourceMappingURL=test/fixtures/simple/style.css.map */
#sidebar {
width: 30%;
background-color: #faa; }
/*# sourceMappingURL=../../../inline */
#header {
color: #6c94be;
}
.pcss {
color: red;
}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIuY3NzIiwidGVzdC9maXh0dXJlcy9zaW1wbGUvc3R5bGUuc3R5bCIsInN0eWxlLnN0eWwiLCJ0ZXN0L2ZpeHR1cmVzL3NpbXBsZS9zdHlsZS5zYXNzIiwic3R5bGUuc2FzcyIsInRlc3QvZml4dHVyZXMvc2ltcGxlL3N0eWxlLmxlc3MiLCJzdHlsZS5sZXNzIiwic3R5bGUucGNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFVBQVU7QUFDWjs7QUNGQTtFQUNFLFdBQU87RUFDUCxnQkFBWTtBQ0NkO0FBQ0EseURBQXlEO0FDSnpEO0VBQ0UsVUFBVTtFQUNWLHNCQUFzQixFQUFBOztBQ0V4QixzQ0FBc0M7QUNEdEM7RUFDRSxjQUFBO0FDRkY7O0FDRkE7RUFDRSxVQUFVO0FBQ1oiLCJmaWxlIjoiYnVuZGxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbImJvZHkge1xuICBjb2xvcjogcmVkO1xufVxuIiwiLmJhciB7XG4gIGNvbG9yOiByZWQ7XG59XG4iLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsLCIucGNzcyB7XG4gIGNvbG9yOiByZWQ7XG59XG4iXX0=*/"
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZvby5jc3MiLCJiYXIuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0UsVUFBVTtBQUNaOztBQ0ZBO0VBQ0UsVUFBVTtBQUNaIiwiZmlsZSI6ImJ1bmRsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcbiAgY29sb3I6IHJlZDtcbn1cbiIsIi5iYXIge1xuICBjb2xvcjogcmVkO1xufVxuIl19*/"
`;

exports[`extract sourcemap-inline: js code 1`] = `
Expand All @@ -279,27 +227,10 @@ exports[`extract sourcemap-true: css code 1`] = `
color: red;
}
body {
color: #f00;
background: #f00;
}
/*# sourceMappingURL=test/fixtures/simple/style.css.map */
#sidebar {
width: 30%;
background-color: #faa; }
#header {
color: #6c94be;
}
.pcss {
color: red;
}
/*# sourceMappingURL=bundle.css.map */"
`;

exports[`extract sourcemap-true: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\",\\"test/fixtures/simple/style.styl\\",\\"style.styl\\",\\"style.sass\\",\\"test/fixtures/simple/style.less\\",\\"style.less\\",\\"style.pcss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ;;ACFA;EACE,WAAO;EACP,gBAAY;ACCd;AACA,yDAAyD;ACJzD;EACE,UAAU;EACV,sBAAsB,EAAE;;ACC1B;EACE,cAAA;ACFF;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"bundle.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\",null,null,\\"#sidebar {\\\\n width: 30%;\\\\n background-color: #faa; }\\\\n\\",null,null,\\".pcss {\\\\n color: red;\\\\n}\\\\n\\"]}"`;
exports[`extract sourcemap-true: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"foo.css\\",\\"bar.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA;EACE,UAAU;AACZ;;ACFA;EACE,UAAU;AACZ\\",\\"file\\":\\"bundle.css\\",\\"sourcesContent\\":[\\"body {\\\\n color: red;\\\\n}\\\\n\\",\\".bar {\\\\n color: red;\\\\n}\\\\n\\"]}"`;

exports[`extract sourcemap-true: js code 1`] = `
"'use strict';
Expand All @@ -316,23 +247,6 @@ exports[`extract true: css code 1`] = `
.bar {
color: red;
}
body {
color: #f00;
background: #f00;
}
#sidebar {
width: 30%;
background-color: #faa; }
#header {
color: #6c94be;
}
.pcss {
color: red;
}
"
`;

Expand Down Expand Up @@ -431,7 +345,7 @@ console.log(css_248z, css_248z$1);
"
`;

exports[`minimize extract: css code 1`] = `".bar,body{color:red}body{background:red}#sidebar{width:30%;background-color:#faa}#header{color:#6c94be}.pcss{color:red}"`;
exports[`minimize extract: css code 1`] = `".bar,body{color:red}"`;

exports[`minimize extract: js code 1`] = `
"'use strict';
Expand All @@ -441,8 +355,8 @@ console.log(undefined, undefined);
`;

exports[`minimize extract-sourcemap-inline: css code 1`] = `
".bar,body{color:red}body{background:red}#sidebar{width:30%;background-color:#faa}#header{color:#6c94be}.pcss{color:red}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJ1bmRsZS5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBUUEsVUFIRSxTQU1GLENBSEEsS0FFRSxjQUNGLENBRUEsU0FDRSxTQUFVLENBQ1YscUJBQXdCLENBRzFCLFFBQ0UsYUFDRixDQUVBLE1BQ0UsU0FDRiIsImZpbGUiOiJidW5kbGUuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiYm9keSB7XG4gIGNvbG9yOiByZWQ7XG59XG5cbi5iYXIge1xuICBjb2xvcjogcmVkO1xufVxuXG5ib2R5IHtcbiAgY29sb3I6ICNmMDA7XG4gIGJhY2tncm91bmQ6ICNmMDA7XG59XG4vKiMgc291cmNlTWFwcGluZ1VSTD10ZXN0L2ZpeHR1cmVzL3NpbXBsZS9zdHlsZS5jc3MubWFwICovXG4jc2lkZWJhciB7XG4gIHdpZHRoOiAzMCU7XG4gIGJhY2tncm91bmQtY29sb3I6ICNmYWE7IH1cblxuLyojIHNvdXJjZU1hcHBpbmdVUkw9Li4vLi4vLi4vaW5saW5lICovXG4jaGVhZGVyIHtcbiAgY29sb3I6ICM2Yzk0YmU7XG59XG5cbi5wY3NzIHtcbiAgY29sb3I6IHJlZDtcbn1cblxuLyojIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2Jhc2U2NCxleUoyWlhKemFXOXVJam96TENKemIzVnlZMlZ6SWpwYkltWnZieTVqYzNNaUxDSmlZWEl1WTNOeklpd2lkR1Z6ZEM5bWFYaDBkWEpsY3k5emFXMXdiR1V2YzNSNWJHVXVjM1I1YkNJc0luTjBlV3hsTG5OMGVXd2lMQ0owWlhOMEwyWnBlSFIxY21WekwzTnBiWEJzWlM5emRIbHNaUzV6WVhOeklpd2ljM1I1YkdVdWMyRnpjeUlzSW5SbGMzUXZabWw0ZEhWeVpYTXZjMmx0Y0d4bEwzTjBlV3hsTG14bGMzTWlMQ0p6ZEhsc1pTNXNaWE56SWl3aWMzUjViR1V1Y0dOemN5SmRMQ0p1WVcxbGN5STZXMTBzSW0xaGNIQnBibWR6SWpvaVFVRkJRVHRGUVVORkxGVkJRVlU3UVVGRFdqczdRVU5HUVR0RlFVTkZMRlZCUVZVN1FVRkRXanM3UVVOR1FUdEZRVU5GTEZkQlFVODdSVUZEVUN4blFrRkJXVHRCUTBOa08wRkJRMEVzZVVSQlFYbEVPMEZEU25wRU8wVkJRMFVzVlVGQlZUdEZRVU5XTEhOQ1FVRnpRaXhGUVVGQk96dEJRMFY0UWl4elEwRkJjME03UVVORWRFTTdSVUZEUlN4alFVRkJPMEZEUmtZN08wRkRSa0U3UlVGRFJTeFZRVUZWTzBGQlExb2lMQ0ptYVd4bElqb2lZblZ1Wkd4bExtTnpjeUlzSW5OdmRYSmpaWE5EYjI1MFpXNTBJanBiSW1KdlpIa2dlMXh1SUNCamIyeHZjam9nY21Wa08xeHVmVnh1SWl3aUxtSmhjaUI3WEc0Z0lHTnZiRzl5T2lCeVpXUTdYRzU5WEc0aUxHNTFiR3dzYm5Wc2JDeHVkV3hzTEc1MWJHd3NiblZzYkN4dWRXeHNMQ0l1Y0dOemN5QjdYRzRnSUdOdmJHOXlPaUJ5WldRN1hHNTlYRzRpWFgwPSovIl19 */"
".bar,body{color:red}
/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJhci5jc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsVUFDRSxTQUNGIiwiZmlsZSI6ImJ1bmRsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIuYmFyIHtcbiAgY29sb3I6IHJlZDtcbn1cbiJdfQ== */"
`;

exports[`minimize extract-sourcemap-inline: js code 1`] = `
Expand All @@ -453,11 +367,11 @@ console.log(undefined, undefined);
`;

exports[`minimize extract-sourcemap-true: css code 1`] = `
".bar,body{color:red}body{background:red}#sidebar{width:30%;background-color:#faa}#header{color:#6c94be}.pcss{color:red}
".bar,body{color:red}
/*# sourceMappingURL=bundle.css.map */"
`;

exports[`minimize extract-sourcemap-true: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"test/fixtures/simple/style.styl\\",\\"bar.css\\",\\"style.styl\\",\\"style.sass\\",\\"test/fixtures/simple/style.less\\",\\"style.less\\",\\"style.pcss\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,UCCE,SCEF,CFHA,KAEE,cECF,CCHA,SACE,SAAU,CACV,qBAAwB,CCC1B,QACE,aCFF,CCFA,MACE,SACF\\",\\"file\\":\\"bundle.css\\",\\"sourcesContent\\":[null,\\".bar {\\\\n color: red;\\\\n}\\\\n\\",null,\\"#sidebar {\\\\n width: 30%;\\\\n background-color: #faa; }\\\\n\\",null,null,\\".pcss {\\\\n color: red;\\\\n}\\\\n\\"]}"`;
exports[`minimize extract-sourcemap-true: css map 1`] = `"{\\"version\\":3,\\"sources\\":[\\"bar.css\\"],\\"names\\":[],\\"mappings\\":\\"AAAA,UACE,SACF\\",\\"file\\":\\"bundle.css\\",\\"sourcesContent\\":[\\".bar {\\\\n color: red;\\\\n}\\\\n\\"]}"`;

exports[`minimize extract-sourcemap-true: js code 1`] = `
"'use strict';
Expand Down Expand Up @@ -762,6 +676,46 @@ console.log(style$1);
"
`;

exports[`multi-entry multi-entry: css code entry1 1`] = `
".baz {
color: red;
}
.foo {
color: red;
}"
`;

exports[`multi-entry multi-entry: css code entry2 1`] = `""`;

exports[`multi-entry multi-entry: js code entry1 1`] = `
"'use strict';
var styles = /*#__PURE__*/Object.freeze({
__proto__: null,
'default': undefined
});
var extraStyles = /*#__PURE__*/Object.freeze({
__proto__: null,
'default': undefined
});
console.log(styles, extraStyles);
"
`;

exports[`multi-entry multi-entry: js code entry2 1`] = `
"'use strict';
var styles = /*#__PURE__*/Object.freeze({
__proto__: null,
'default': undefined
});
console.log(styles);
"
`;

exports[`onExtract 1`] = `
"'use strict';
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/multi-entry/entry1-extra.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.foo {
color: red;
}
3 changes: 3 additions & 0 deletions test/fixtures/multi-entry/entry1.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.baz {
color: red;
}
4 changes: 4 additions & 0 deletions test/fixtures/multi-entry/entry1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as styles from './entry1.css'
import * as extraStyles from './entry1-extra.css'

console.log(styles, extraStyles)
Empty file.
3 changes: 3 additions & 0 deletions test/fixtures/multi-entry/entry2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as styles from './entry2.css'

console.log(styles)
Loading

0 comments on commit 3ea986c

Please sign in to comment.