Skip to content

Commit

Permalink
feat: allow multiple entry files and outputs
Browse files Browse the repository at this point in the history
Bundle multiple bundles for multiple input entries.
  • Loading branch information
chmelevskij committed Apr 19, 2020
1 parent 0e71f75 commit 5dd0e27
Show file tree
Hide file tree
Showing 10 changed files with 196 additions and 57 deletions.
90 changes: 51 additions & 39 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default (options = {}) => {
options.plugins
const { sourceMap } = options
const postcssLoaderOptions = {
multiEntry:
typeof options.multiEntry === 'undefined' ? false : options.multiEntry,
/** Inject CSS as `<style>` to `<head>` */
inject: typeof options.inject === 'function' ? options.inject : inferOption(options.inject, {}),
/** Extract CSS */
Expand Down Expand Up @@ -129,39 +131,41 @@ export default (options = {}) => {
) return

// 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 = ({ fileName: entryFileName, modules }) => {
let baseName = `${path.basename(entryFileName, path.extname(entryFileName))}.css`
let fileName = path.join(
path.dirname(entryFileName),
baseName
)
const getExtracted = () => {
let fileName = `${path.basename(file, path.extname(file))}.css`
if (typeof postcssLoaderOptions.extract === 'string') {
if (path.isAbsolute(postcssLoaderOptions.extract)) {
fileName = normalizePath(path.relative(dir, postcssLoaderOptions.extract))
fileName = normalizePath(path.relative(path.dirname(entryFileName), postcssLoaderOptions.extract))
} else {
fileName = normalizePath(postcssLoaderOptions.extract)
}
baseName = fileName
}

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)
)
}

for (const result of entries) {
const relative = normalizePath(path.relative(dir, result.id))
const relative = normalizePath(path.relative(path.dirname(fileName), 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 +179,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 +197,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 cssOpts = postcssLoaderOptions.minimize
cssOpts.from = codeFileName
if (sourceMap === 'inline') {
cssOpts.map = { inline: true }
} else if (sourceMap === true && map) {
cssOpts.map = { prev: map }
cssOpts.to = codeFileName
}

const result = await require('cssnano').process(code, cssOptions)
code = result.css
const result = await require('cssnano').process(code, cssOpts)
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)
)
}
}
}
6 changes: 3 additions & 3 deletions src/sass-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ export default {
// Give precedence to importing a partial
resolvePromise(partialUrl, options)
.then(finishImport)
.catch(error => {
.catch(err => {
if (
error.code === 'MODULE_NOT_FOUND' ||
error.code === 'ENOENT'
err.code === 'MODULE_NOT_FOUND' ||
err.code === 'ENOENT'
) {
resolvePromise(moduleUrl, options)
.then(finishImport)
Expand Down
2 changes: 1 addition & 1 deletion src/utils/load-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function loadModule(moduleId) {
// Trying to load module normally (relative to plugin directory)
try {
return require(moduleId)
} catch (_) {
} catch (err) {
// Ignore error
}

Expand Down
47 changes: 47 additions & 0 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,53 @@ 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 5dd0e27

Please sign in to comment.