diff --git a/README.md b/README.md index dbea3e9b..673ead99 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,7 @@ To disable `url()` resolving by `css-loader` set the option to `false` #### `{Function}` + **webpack.config.js** ```js { @@ -145,6 +146,32 @@ To disable `@import` resolving by `css-loader` set the option to `false` } ``` +#### `{RegExp}` + +**webpack.config.js** +```js +{ + loader: 'css-loader', + options: { + import: /filter/ + } +} +``` + +#### `{Function}` + +**webpack.config.js** +```js +{ + loader: 'css-loader', + options: { + import (url) { + return /filter/.test(url) + } + } +} +``` + ### `minimize` #### `{Boolean}` diff --git a/src/index.js b/src/index.js index 0e2710f3..a28f2050 100644 --- a/src/index.js +++ b/src/index.js @@ -53,7 +53,7 @@ export default function loader(css, map, meta) { // Import Plugin if (options.import) { - plugins.push(imports()); + plugins.push(imports(options)); } // Minifier diff --git a/src/options.json b/src/options.json index 3ecc7e64..d2182106 100644 --- a/src/options.json +++ b/src/options.json @@ -10,7 +10,12 @@ ] }, "import": { - "type": "boolean" + "anyOf": [ + { "type": "string" }, + { "type": "boolean" }, + { "instanceof": "RegExp" }, + { "instanceof": "Function" } + ] }, "minimize": { "type": "boolean" diff --git a/src/plugins/import.js b/src/plugins/import.js index 509b0ff1..86353b39 100644 --- a/src/plugins/import.js +++ b/src/plugins/import.js @@ -1,8 +1,8 @@ /* eslint-disable */ import postcss from 'postcss'; import valueParser from 'postcss-value-parser'; -// ICSS {String} -// import { createICSSRules } from "icss-utils"; + +const plugin = 'postcss-icss-import'; const getArg = nodes => (nodes.length !== 0 && nodes[0].type === 'string' @@ -38,19 +38,39 @@ const parseImport = (params) => { }; }; -const isExternalUrl = url => /^\w+:\/\//.test(url) || url.startsWith('//'); +const URL = /^\w+:\/\//; + +const filter = (url, options) => { + if (URL.test(url)) { + return true; + } + + if (url.startsWith('//')) { + return true; + } + + if (options.import instanceof RegExp) { + return options.import.test(url); + } + + if (typeof options.import === 'function') { + return options.import(url); + } -const walkImports = (css, callback) => { + return false; +} + +const walkImports = (css, cb) => { css.each((node) => { if (node.type === 'atrule' && node.name.toLowerCase() === 'import') { - callback(node); + cb(node); } }); }; -const plugin = 'postcss-icss-import'; +export default postcss.plugin(plugin, (options) => (css, result) => { + let idx = 0; -export default postcss.plugin(plugin, () => (css, result) => { walkImports(css, (atrule) => { if (atrule.nodes) { return result.warn( @@ -62,7 +82,7 @@ export default postcss.plugin(plugin, () => (css, result) => { const parsed = parseImport(atrule.params); if (parsed === null) { - return result.warn(`Unable to find uri in '${atrule.toString()}'`, { + return result.warn(`Unable to find URI in '${atrule.toString()}'`, { node: atrule, }); } @@ -70,7 +90,7 @@ export default postcss.plugin(plugin, () => (css, result) => { let idx = 0; const url = parsed.url; - if (!isExternalUrl(url)) { + if (!filter(url, options)) { atrule.remove(); result.messages.push({ @@ -82,4 +102,4 @@ export default postcss.plugin(plugin, () => (css, result) => { idx++; } }); -}); +}); \ No newline at end of file diff --git a/test/fixtures/import/filter/fixture.css b/test/fixtures/import/filter/fixture.css new file mode 100644 index 00000000..5ecf8c5f --- /dev/null +++ b/test/fixtures/import/filter/fixture.css @@ -0,0 +1,6 @@ +@import './import.css'; +@import './filter/import.css'; + +.css { + width: 100%; +} diff --git a/test/fixtures/imports/fixture.js b/test/fixtures/import/filter/fixture.js similarity index 100% rename from test/fixtures/imports/fixture.js rename to test/fixtures/import/filter/fixture.js diff --git a/test/fixtures/imports/fixture.css b/test/fixtures/import/fixture.css similarity index 100% rename from test/fixtures/imports/fixture.css rename to test/fixtures/import/fixture.css diff --git a/test/fixtures/import/fixture.js b/test/fixtures/import/fixture.js new file mode 100644 index 00000000..8c459de3 --- /dev/null +++ b/test/fixtures/import/fixture.js @@ -0,0 +1,3 @@ +import css from './fixture.css'; + +export default css; diff --git a/test/fixtures/imports/import.css b/test/fixtures/import/import.css similarity index 100% rename from test/fixtures/imports/import.css rename to test/fixtures/import/import.css diff --git a/test/options/__snapshots__/import.test.js.snap b/test/options/__snapshots__/import.test.js.snap index f2b2f330..a58a54f1 100644 --- a/test/options/__snapshots__/import.test.js.snap +++ b/test/options/__snapshots__/import.test.js.snap @@ -11,3 +11,31 @@ export default \`.fixture { } \`" `; + +exports[`Options import {Function} 1`] = ` +"// CSS Imports +import CSS__IMPORT__0 from './import.css'; + + +// CSS +export default \`@import './filter/import.css'; + +.css { + width: 100%; +} +\`" +`; + +exports[`Options import {RegExp} 1`] = ` +"// CSS Imports +import CSS__IMPORT__0 from './import.css'; + + +// CSS +export default \`@import './filter/import.css'; + +.css { + width: 100%; +} +\`" +`; diff --git a/test/options/import.test.js b/test/options/import.test.js index bc418d0c..f01360ba 100644 --- a/test/options/import.test.js +++ b/test/options/import.test.js @@ -13,7 +13,41 @@ describe('Options', () => { }, }; - const stats = await webpack('imports/fixture.js', config); + const stats = await webpack('import/fixture.js', config); + const { source } = stats.toJson().modules[1]; + + expect(source).toMatchSnapshot(); + }); + + test('{RegExp}', async () => { + const config = { + loader: { + test: /\.css$/, + options: { + import: /filter/, + }, + }, + }; + + const stats = await webpack('import/filter/fixture.js', config); + const { source } = stats.toJson().modules[1]; + + expect(source).toMatchSnapshot(); + }); + + test('{Function}', async () => { + const config = { + loader: { + test: /\.css$/, + options: { + import(url) { + return /filter/.test(url); + }, + }, + }, + }; + + const stats = await webpack('import/filter/fixture.js', config); const { source } = stats.toJson().modules[1]; expect(source).toMatchSnapshot(); diff --git a/test/options/sourceMap.test.js b/test/options/sourceMap.test.js index 29bd9ef6..a128dca9 100644 --- a/test/options/sourceMap.test.js +++ b/test/options/sourceMap.test.js @@ -1,7 +1,7 @@ /* eslint-disable - prefer-destructuring, no-param-reassign, no-underscore-dangle, + prefer-destructuring, */ import path from 'path'; import webpack from '../helpers/compiler';