diff --git a/README.md b/README.md index 30d8c900..f03b21e2 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,42 @@ import style from './file.css'; style.className === 'z849f98ca812'; ``` -### `Useable` +## Options + +| Name | Type | Default | Description | +| :--------------: | :------------------: | :--------: | :------------------------------------------------- | +| **`injectType`** | `{String}` | `styleTag` | Allows to setup how styles will be injected in DOM | +| **`attributes`** | `{Object}` | `{}` | Add custom attributes to tag | +| **`insertAt`** | `{String\|Object}` | `bottom` | Inserts tag at the given position | +| **`insertInto`** | `{String\|Function}` | `` | Inserts tag into the given position | +| **`base`** | `{Number}` | `true` | Set module ID base (DLLPlugin) | + +### `injectType` + +Type: `String` +Default: `styleTag` + +Allows to setup how styles will be injected in DOM. -The `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()` +Possible values: + +- `styleTag` +- `singletonStyleTag` +- `lazyStyleTag` +- `lazySingletonStyleTag` +- `linkTag` + +When you `lazyStyleTag` or `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`. +It is named `Reference Counter API`. + +**component.js** + +```js +import style from './file.css'; + +style.use(); // = style.ref(); +style.unuse(); // = style.unref(); +``` By convention the `Reference Counter API` should be bound to `.useable.css` and the `.css` should be loaded with basic `style-loader` usage.(similar to other file types, i.e. `.useable.less` and `.less`). @@ -84,15 +117,19 @@ module.exports = { module: { rules: [ { - test: /\.css$/, - exclude: /\.useable\.css$/, + test: /\.css$/i, + exclude: /\.useable\.css$/i, use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], }, { - test: /\.useable\.css$/, + test: /\.useable\.css$/i, use: [ { - loader: 'style-loader/useable', + loader: 'style-loader', + options: { + // Can be `'lazyStyleTag'` or `'lazySingletonStyleTag'` + injectType: 'lazyStyleTag', + }, }, { loader: 'css-loader' }, ], @@ -102,27 +139,57 @@ module.exports = { }; ``` -#### `Reference Counter API` +Styles are not added on `import/require()`, but instead on call to `use`/`ref`. Styles are removed from page if `unuse`/`unref` is called exactly as often as `use`/`ref`. -**component.js** +> ⚠️ Behavior is undefined when `unuse`/`unref` is called more often than `use`/`ref`. Don't do that. + +#### `styleTag` + +Injects styles in multiple ``. It is **default** behaviour. ```js -import style from './file.css'; +import './styles.css'; +``` -style.use(); // = style.ref(); -style.unuse(); // = style.unref(); +**webpack.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { loader: 'style-loader', options: { injectType: 'styleTag' } }, + 'css-loader', + ], + }, + ], + }, +}; ``` -Styles are not added on `import/require()`, but instead on call to `use`/`ref`. Styles are removed from page if `unuse`/`unref` is called exactly as often as `use`/`ref`. +The loader inject styles like: -> ⚠️ Behavior is undefined when `unuse`/`unref` is called more often than `use`/`ref`. Don't do that. +```html + + +``` -### `Url` +#### `singletonStyleTag` -It's also possible to add a URL `` instead of inlining the CSS `{String}` with `` tag. +Injects styles in one ``. ```js -import url from 'file.css'; +import './styles.css'; ``` **webpack.config.js** @@ -132,45 +199,54 @@ module.exports = { module: { rules: [ { - test: /\.css$/, - use: [{ loader: 'style-loader/url' }, { loader: 'file-loader' }], + test: /\.css$/i, + use: [ + { + loader: 'style-loader', + options: { injectType: 'singletonStyleTag' }, + }, + 'css-loader', + ], }, ], }, }; ``` +The loader inject styles like: + ```html - + ``` -## Options +#### `lazyStyleTag` -| Name | Type | Default | Description | -| :--------------: | :------------------: | :---------: | :------------------------------------------------------------------------------------------------------------------ | -| **`base`** | `{Number}` | `true` | Set module ID base (DLLPlugin) | -| **`attributes`** | `{Object}` | `{}` | Add custom attributes to `` | -| **`insertAt`** | `{String\|Object}` | `bottom` | Inserts `` at the given position | -| **`insertInto`** | `{String\|Function}` | `` | Inserts `` into the given position | -| **`singleton`** | `{Boolean}` | `undefined` | Reuses a single `` element, instead of adding/removing individual elements for each required module. | +Injects styles in multiple `` on demand (documentation above). -### `base` +```js +import styles from './styles.css'; -This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.github.io/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.: +styles.use(); +``` -**webpack.dll1.config.js** +**webpack.config.js** ```js module.exports = { module: { rules: [ { - test: /\.css$/i, + test: /\.useable\.css$/i, use: [ - { - loader: 'style-loader', - }, - { loader: 'css-loader' }, + { loader: 'style-loader', options: { injectType: 'lazyStyleTag' } }, + 'css-loader', ], }, ], @@ -178,17 +254,45 @@ module.exports = { }; ``` -**webpack.dll2.config.js** +The loader inject styles like: + +```html + + +``` + +#### `lazySingletonStyleTag` + +Injects styles in one `` on demand (documentation above). + +```js +import styles from './styles.css'; + +styles.use(); +``` + +**webpack.config.js** ```js module.exports = { module: { rules: [ { - test: /\.css$/, + test: /\.useable\.css$/i, use: [ - { loader: 'style-loader', options: { base: 1000 } }, - { loader: 'css-loader' }, + { + loader: 'style-loader', + options: { injectType: 'lazySingletonStyleTag' }, + }, + 'css-loader', ], }, ], @@ -196,17 +300,39 @@ module.exports = { }; ``` -**webpack.app.config.js** +The loader generate this: + +```html + +``` + +#### `linkTag` + +Injects styles in multiple `` . + +```js +import './styles.css'; +import './other-styles.css'; +``` + +**webpack.config.js** ```js module.exports = { module: { rules: [ { - test: /\.css$/, + test: /\.css$/i, use: [ - { loader: 'style-loader', options: { base: 2000 } }, - { loader: 'css-loader' }, + { loader: 'style-loader', options: { injectType: 'linkTag' } }, + { loader: 'file-loader' }, ], }, ], @@ -214,8 +340,18 @@ module.exports = { }; ``` +The loader generate this: + +```html + + +``` + ### `attributes` +Type: `Object` +Default: `{}` + If defined, style-loader will attach given attributes with their values on `` element, instead of adding/removing individual elements for each required module. +This setting is primarily used as a workaround for [css clashes](https://github.com/webpack-contrib/style-loader/issues/163) when using one or more [DllPlugin](https://robertknight.github.io/posts/webpack-dll-plugins/)'s. `base` allows you to prevent either the _app_'s css (or _DllPlugin2_'s css) from overwriting _DllPlugin1_'s css by specifying a css module id base which is greater than the range used by _DllPlugin1_ e.g.: -> ℹ️ This option is on by default in IE9, which has strict limitations on the number of style tags allowed on a page. You can enable or disable it with the singleton option. +**webpack.dll1.config.js** -**webpack.config.js** +```js +module.exports = { + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { + loader: 'style-loader', + }, + { loader: 'css-loader' }, + ], + }, + ], + }, +}; +``` + +**webpack.dll2.config.js** + +```js +module.exports = { + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { loader: 'style-loader', options: { base: 1000 } }, + { loader: 'css-loader' }, + ], + }, + ], + }, +}; +``` + +**webpack.app.config.js** ```js module.exports = { @@ -369,7 +541,7 @@ module.exports = { { test: /\.css$/i, use: [ - { loader: 'style-loader', options: { singleton: true } }, + { loader: 'style-loader', options: { base: 2000 } }, { loader: 'css-loader' }, ], }, diff --git a/package.json b/package.json index b20d8898..86911bbe 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,7 @@ "defaults": "webpack-defaults" }, "files": [ - "dist", - "url.js", - "useable.js" + "dist" ], "peerDependencies": { "webpack": "^4.0.0" diff --git a/src/index.js b/src/index.js index 0199f4d4..c04b50ff 100644 --- a/src/index.js +++ b/src/index.js @@ -30,7 +30,105 @@ module.exports.pitch = function loader(request) { insertInto = `"${options.insertInto}"`; } - const hmrCode = ` + const injectType = options.injectType || 'styleTag'; + + switch (injectType) { + case 'linkTag': { + const hmrCode = this.hot + ? ` +if (module.hot) { + module.hot.accept( + ${loaderUtils.stringifyRequest(this, `!!${request}`)}, + function() { + update(require(${loaderUtils.stringifyRequest(this, `!!${request}`)})); + } + ); + + module.hot.dispose(function() { + update(); + }); +}` + : ''; + + return `var update = require(${loaderUtils.stringifyRequest( + this, + `!${path.join(__dirname, 'runtime/addStyleUrl.js')}` + )})(require(${loaderUtils.stringifyRequest( + this, + `!!${request}` + )}), ${JSON.stringify(options)}); + ${hmrCode}`; + } + + case 'lazyStyleTag': + case 'lazySingletonStyleTag': { + const isSingleton = injectType === 'lazySingletonStyleTag'; + + const hmrCode = this.hot + ? ` +if (module.hot) { + var lastRefs = module.hot.data && module.hot.data.refs || 0; + + if (lastRefs) { + exports.ref(); + if (!content.locals) { + refs = lastRefs; + } + } + + if (!content.locals) { + module.hot.accept(); + } + + module.hot.dispose(function(data) { + data.refs = content.locals ? 0 : refs; + + if (dispose) { + dispose(); + } + }); +}` + : ''; + + return `var refs = 0; +var dispose; +var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)}); +var options = ${JSON.stringify(options)}; + +options.insertInto = ${insertInto}; +options.singleton = ${isSingleton}; + +if (typeof content === 'string') content = [[module.id, content, '']]; +if (content.locals) exports.locals = content.locals; + +exports.use = exports.ref = function() { + if (!(refs++)) { + dispose = require(${loaderUtils.stringifyRequest( + this, + `!${path.join(__dirname, 'runtime/addStyles.js')}` + )})(content, options); + } + + return exports; +}; + +exports.unuse = exports.unref = function() { + if (refs > 0 && !--refs) { + dispose(); + dispose = null; + } +}; +${hmrCode} +`; + } + + case 'styleTag': + case 'singletonStyleTag': + default: { + const isSingleton = injectType === 'singletonStyleTag'; + + const hmrCode = this.hot + ? ` if (module.hot) { module.hot.accept( ${loaderUtils.stringifyRequest(this, `!!${request}`)}, @@ -67,10 +165,13 @@ if (module.hot) { module.hot.dispose(function() { update(); }); -}`; +}` + : ''; - return ` -var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)}); + return `var content = require(${loaderUtils.stringifyRequest( + this, + `!!${request}` + )}); if (typeof content === 'string') content = [[module.id, content, '']]; @@ -79,13 +180,15 @@ var insertInto; var options = ${JSON.stringify(options)} options.insertInto = ${insertInto}; +options.singleton = ${isSingleton}; var update = require(${loaderUtils.stringifyRequest( - this, - `!${path.join(__dirname, 'runtime/addStyles.js')}` - )})(content, options); + this, + `!${path.join(__dirname, 'runtime/addStyles.js')}` + )})(content, options); if (content.locals) module.exports = content.locals; -${this.hot ? hmrCode : ''} -`; +${hmrCode}`; + } + } }; diff --git a/src/options.json b/src/options.json index 05ebb503..77d6ce74 100644 --- a/src/options.json +++ b/src/options.json @@ -5,6 +5,16 @@ "description": "Set module ID base for DLLPlugin (https://github.com/webpack-contrib/style-loader#base).", "type": "number" }, + "injectType": { + "description": "Allows to setup how styles will be injected in DOM.", + "enum": [ + "styleTag", + "singletonStyleTag", + "lazyStyleTag", + "lazySingletonStyleTag", + "linkTag" + ] + }, "attributes": { "description": "Add custom attributes to tag (https://github.com/webpack-contrib/style-loader#attributes).", "type": "object" @@ -16,10 +26,6 @@ "insertInto": { "description": "Inserts into the given position (https://github.com/webpack-contrib/style-loader#insertinto).", "anyOf": [{ "type": "string" }, { "instanceof": "Function" }] - }, - "singleton": { - "description": "Reuses a single element, instead of adding/removing individual elements for each required module (https://github.com/webpack-contrib/style-loader#singleton).", - "type": "boolean" } }, "additionalProperties": false diff --git a/src/runtime/addStyleUrl.js b/src/runtime/addStyleUrl.js index 7ff4cee7..87166f3d 100644 --- a/src/runtime/addStyleUrl.js +++ b/src/runtime/addStyleUrl.js @@ -15,6 +15,15 @@ module.exports = function addStyleUrl(url, options) { options.attributes = typeof options.attributes === 'object' ? options.attributes : {}; + if (options.attributes.nonce === undefined) { + var nonce = + typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null; + + if (nonce) { + options.attributes.nonce = nonce; + } + } + const link = document.createElement('link'); link.rel = 'stylesheet'; diff --git a/src/url-loader.js b/src/url-loader.js deleted file mode 100644 index ecebd3d7..00000000 --- a/src/url-loader.js +++ /dev/null @@ -1,40 +0,0 @@ -import path from 'path'; - -import loaderUtils from 'loader-utils'; -import validateOptions from 'schema-utils'; - -import schema from './options.json'; - -module.exports = () => {}; - -module.exports.pitch = function loader(request) { - const options = loaderUtils.getOptions(this) || {}; - - validateOptions(schema, options, { - name: 'Style Loader (URL)', - baseDataPath: 'options', - }); - - const hmrCode = ` -if (module.hot) { - module.hot.accept( - ${loaderUtils.stringifyRequest(this, `!!${request}`)}, - function() { - update(require(${loaderUtils.stringifyRequest(this, `!!${request}`)})); - } - ); - - module.hot.dispose(function() { - update(); - }); -}`; - - return `var update = require(${loaderUtils.stringifyRequest( - this, - `!${path.join(__dirname, 'runtime/addStyleUrl.js')}` - )})(require(${loaderUtils.stringifyRequest( - this, - `!!${request}` - )}), ${JSON.stringify(options)}); - ${this.hot ? hmrCode : ''}`; -}; diff --git a/src/useable-loader.js b/src/useable-loader.js deleted file mode 100644 index 0204dab1..00000000 --- a/src/useable-loader.js +++ /dev/null @@ -1,87 +0,0 @@ -import path from 'path'; - -import loaderUtils from 'loader-utils'; -import validateOptions from 'schema-utils'; - -import schema from './options.json'; - -module.exports = () => {}; - -module.exports.pitch = function loader(request) { - const options = loaderUtils.getOptions(this) || {}; - - validateOptions(schema, options, { - name: 'Style Loader (Useable)', - baseDataPath: 'options', - }); - - // The variable is needed, because the function should be inlined. - // If is just stored it in options, JSON.stringify will quote - // the function and it would be just a string at runtime - let insertInto; - - if (typeof options.insertInto === 'function') { - insertInto = options.insertInto.toString(); - } - - // We need to check if it a string, or variable will be "undefined" - // and the loader crashes - if (typeof options.insertInto === 'string') { - insertInto = `"${options.insertInto}"`; - } - - const hmrCode = ` -if (module.hot) { - var lastRefs = module.hot.data && module.hot.data.refs || 0; - - if (lastRefs) { - exports.ref(); - if (!content.locals) { - refs = lastRefs; - } - } - - if (!content.locals) { - module.hot.accept(); - } - - module.hot.dispose(function(data) { - data.refs = content.locals ? 0 : refs; - - if (dispose) { - dispose(); - } - }); -}`; - - return ` -var refs = 0; -var dispose; -var content = require(${loaderUtils.stringifyRequest(this, `!!${request}`)}); -var options = ${JSON.stringify(options)}; - -options.insertInto = ${insertInto}; - -if (typeof content === 'string') content = [[module.id, content, '']]; -if (content.locals) exports.locals = content.locals; - -exports.use = exports.ref = function() { - if (!(refs++)) { - dispose = require(${loaderUtils.stringifyRequest( - this, - `!${path.join(__dirname, 'runtime/addStyles.js')}` - )})(content, options); - } - - return exports; -}; - -exports.unuse = exports.unref = function() { - if (refs > 0 && !--refs) { - dispose(); - dispose = null; - } -}; -${this.hot ? hmrCode : ''} -`; -}; diff --git a/test/__snapshots__/attributes-option.test.js.snap b/test/__snapshots__/attributes-option.test.js.snap index 903f757f..6893144a 100644 --- a/test/__snapshots__/attributes-option.test.js.snap +++ b/test/__snapshots__/attributes-option.test.js.snap @@ -1,10 +1,58 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`attributes option should add attributes to tag ("injectType" option is "linkTag"): DOM 1`] = ` +exports[`attributes option should add attributes to tag when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` " style-loader test - + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "lazyStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; + +exports[`attributes option should add attributes to tag when the "injectType" option is "linkTag": DOM 1`] = ` +" + style-loader test + +

Body

@@ -14,17 +62,20 @@ exports[`attributes option should add attributes to tag ("injectType" option is " `; -exports[`attributes option should add attributes to tag ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "linkTag": errors 1`] = `Array []`; -exports[`attributes option should add attributes to tag ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "linkTag": warnings 1`] = `Array []`; -exports[`attributes option should add attributes to tag ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`attributes option should add attributes to tag when the "injectType" option is "singletonStyleTag": DOM 1`] = ` " style-loader test -

Body

@@ -35,15 +86,18 @@ exports[`attributes option should add attributes to tag ("injectType" option is " `; -exports[`attributes option should add attributes to tag ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; -exports[`attributes option should add attributes to tag ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; -exports[`attributes option should add attributes to tag ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`attributes option should add attributes to tag when the "injectType" option is "styleTag": DOM 1`] = ` " style-loader test - @@ -56,11 +110,11 @@ exports[`attributes option should add attributes to tag ("injectType" option is " `; -exports[`attributes option should add attributes to tag ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "styleTag": errors 1`] = `Array []`; -exports[`attributes option should add attributes to tag ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`attributes option should add attributes to tag when the "injectType" option is "styleTag": warnings 1`] = `Array []`; -exports[`attributes option should add nonce attribute #2: DOM 1`] = ` +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag" #2: DOM 1`] = ` " style-loader test @@ -77,11 +131,11 @@ exports[`attributes option should add nonce attribute #2: DOM 1`] = ` " `; -exports[`attributes option should add nonce attribute #2: errors 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag" #2: errors 1`] = `Array []`; -exports[`attributes option should add nonce attribute #2: warnings 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag" #2: warnings 1`] = `Array []`; -exports[`attributes option should add nonce attribute: DOM 1`] = ` +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` " style-loader test @@ -98,15 +152,18 @@ exports[`attributes option should add nonce attribute: DOM 1`] = ` " `; -exports[`attributes option should add nonce attribute: errors 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; -exports[`attributes option should add nonce attribute: warnings 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "linkTag"): DOM 1`] = ` +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: DOM 1`] = ` " style-loader test - +

Body

@@ -116,15 +173,15 @@ exports[`attributes option should override/add default type attribute to tag ("i " `; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: errors 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: warnings 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag": DOM 1`] = ` " style-loader test - @@ -137,16 +194,115 @@ exports[`attributes option should override/add default type attribute to tag ("i " `; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`attributes option should add nonce attribute when "injectType" option is "linkTag" #2: DOM 1`] = ` " style-loader test - + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add nonce attribute when "injectType" option is "linkTag": errors 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "linkTag": warnings 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag" #2: DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag" #2: errors 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag" #2: warnings 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag" #2: DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag" #2: errors 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag" #2: warnings 1`] = `Array []`; + +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag": DOM 1`] = ` +" + style-loader test + + @@ -158,6 +314,6 @@ exports[`attributes option should override/add default type attribute to tag ("i " `; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag": errors 1`] = `Array []`; -exports[`attributes option should override/add default type attribute to tag ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`attributes option should add nonce attribute when "injectType" option is "styleTag": warnings 1`] = `Array []`; diff --git a/test/__snapshots__/base-option.test.js.snap b/test/__snapshots__/base-option.test.js.snap index 4345f9e7..b11e58c8 100644 --- a/test/__snapshots__/base-option.test.js.snap +++ b/test/__snapshots__/base-option.test.js.snap @@ -7,6 +7,9 @@ exports[`base option should work: DOM 1`] = `

Body

diff --git a/test/__snapshots__/injectType-option.test.js.snap b/test/__snapshots__/injectType-option.test.js.snap new file mode 100644 index 00000000..1591f1bb --- /dev/null +++ b/test/__snapshots__/injectType-option.test.js.snap @@ -0,0 +1,115 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`injectType option should work when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`injectType option should work when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "lazyStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`injectType option should work when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "linkTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`injectType option should work when the "injectType" option is "linkTag": errors 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "linkTag": warnings 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "singletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`injectType option should work when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "styleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`injectType option should work when the "injectType" option is "styleTag": errors 1`] = `Array []`; + +exports[`injectType option should work when the "injectType" option is "styleTag": warnings 1`] = `Array []`; diff --git a/test/__snapshots__/insert-option.test.js.snap b/test/__snapshots__/insert-option.test.js.snap index 7e5d5b4a..b3e229d2 100644 --- a/test/__snapshots__/insert-option.test.js.snap +++ b/test/__snapshots__/insert-option.test.js.snap @@ -6,6 +6,9 @@ exports[`insert option should insert styles before "#existing-style" id: DOM 1`] @@ -49,6 +52,9 @@ exports[`insert option should insert styles in bottom when not specified: DOM 1`

Body

@@ -70,6 +76,9 @@ exports[`insert option should insert styles in bottom when selector was not foun

Body

@@ -91,6 +100,9 @@ exports[`insert option should insert styles in bottom: DOM 1`] = `

Body

@@ -130,6 +142,9 @@ exports[`insert option should insert styles in top: DOM 1`] = ` " style-loader test @@ -167,6 +182,9 @@ exports[`insert option should insert styles into target when target is iframe: i "" `; @@ -182,6 +200,9 @@ exports[`insert option should insert styles into target: DOM 1`] = `
diff --git a/test/__snapshots__/loader.test.js.snap b/test/__snapshots__/loader.test.js.snap index f91aa82c..d10d7e1f 100644 --- a/test/__snapshots__/loader.test.js.snap +++ b/test/__snapshots__/loader.test.js.snap @@ -1,10 +1,16 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "linkTag"): DOM 1`] = ` +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` " style-loader test - +

Body

@@ -14,11 +20,11 @@ exports[`loader should generate source maps when previous loader emit them ("inj " `; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazyStyleTag": DOM 1`] = ` " style-loader test @@ -26,7 +32,29 @@ exports[`loader should generate source maps when previous loader emit them ("inj color: red; } -/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWiIsImZpbGUiOiJzdHlsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcbiAgY29sb3I6IHJlZDtcbn1cbiJdfQ== */ +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLFVBQVU7QUFDWiIsImZpbGUiOiJzdHlsZS5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyJib2R5IHtcbiAgY29sb3I6IHJlZDtcbn1cbiJdfQ== */ + +

Body

+
+ + + +" +`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "linkTag": DOM 1`] = ` +" + style-loader test + +

Body

@@ -36,15 +64,43 @@ exports[`loader should generate source maps when previous loader emit them ("inj " `; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "linkTag": errors 1`] = `Array []`; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "linkTag": warnings 1`] = `Array []`; -exports[`loader should generate source maps when previous loader emit them ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "singletonStyleTag": DOM 1`] = ` " style-loader test - + +

Body

+
+ + + +" +`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; + +exports[`loader should generate source maps when previous loader emit them when the "injectType" option is "styleTag": DOM 1`] = ` +" + style-loader test + + - +

Body

@@ -88,17 +158,62 @@ exports[`loader should not generate source maps when previous loader don't emit " `; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "lazyStyleTag": DOM 1`] = ` " style-loader test + +

Body

+
+ + + +" +`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "linkTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "linkTag": errors 1`] = `Array []`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "linkTag": warnings 1`] = `Array []`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "singletonStyleTag": DOM 1`] = ` +" + style-loader test + +

Body

@@ -109,15 +224,18 @@ exports[`loader should not generate source maps when previous loader don't emit " `; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "styleTag": DOM 1`] = ` " style-loader test - @@ -130,27 +248,38 @@ exports[`loader should not generate source maps when previous loader don't emit " `; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "styleTag": errors 1`] = `Array []`; + +exports[`loader should not generate source maps when previous loader don't emit them when the "injectType" option is "styleTag": warnings 1`] = `Array []`; + +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; + +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should not generate source maps when previous loader don't emit them ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "linkTag": errors 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "linkTag": warnings 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "styleTag": errors 1`] = `Array []`; -exports[`loader should work ("injectType" option is "linkTag"): DOM 1`] = ` +exports[`loader should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "styleTag": warnings 1`] = `Array []`; + +exports[`loader should work when ref is negative when the "injectType" option is "lazySingletonStyleTag"): DOM 1`] = ` " style-loader test - +

Body

@@ -160,11 +289,11 @@ exports[`loader should work ("injectType" option is "linkTag"): DOM 1`] = ` " `; -exports[`loader should work ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`loader should work when ref is negative when the "injectType" option is "lazySingletonStyleTag"): errors 1`] = `Array []`; -exports[`loader should work ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`loader should work when ref is negative when the "injectType" option is "lazySingletonStyleTag"): warnings 1`] = `Array []`; -exports[`loader should work ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`loader should work when ref is negative when the "injectType" option is "lazyStyleTag"): DOM 1`] = ` " style-loader test @@ -181,15 +310,18 @@ exports[`loader should work ("injectType" option is "styleTag"): DOM 1`] = ` " `; -exports[`loader should work ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`loader should work when ref is negative when the "injectType" option is "lazyStyleTag"): errors 1`] = `Array []`; -exports[`loader should work ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`loader should work when ref is negative when the "injectType" option is "lazyStyleTag"): warnings 1`] = `Array []`; -exports[`loader should work ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`loader should work when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` " style-loader test - @@ -202,17 +334,20 @@ exports[`loader should work ("injectType" option is "useableStyleTag"): DOM 1`] " `; -exports[`loader should work ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`loader should work when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; -exports[`loader should work ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`loader should work when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should work for useable inject type and negative ref: DOM 1`] = ` +exports[`loader should work when the "injectType" option is "lazyStyleTag": DOM 1`] = ` " style-loader test

Body

@@ -223,29 +358,105 @@ exports[`loader should work for useable inject type and negative ref: DOM 1`] = " `; -exports[`loader should work for useable inject type and negative ref: errors 1`] = `Array []`; +exports[`loader should work when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; -exports[`loader should work for useable inject type and negative ref: warnings 1`] = `Array []`; +exports[`loader should work when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "linkTag"): DOM 1`] = ` +exports[`loader should work when the "injectType" option is "linkTag": DOM 1`] = ` " style-loader test - +

Body

-
Water
Ground
" +" +`; + +exports[`loader should work when the "injectType" option is "linkTag": errors 1`] = `Array []`; + +exports[`loader should work when the "injectType" option is "linkTag": warnings 1`] = `Array []`; + +exports[`loader should work when the "injectType" option is "singletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`loader should work when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; + +exports[`loader should work when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; + +exports[`loader should work when the "injectType" option is "styleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`loader should work when the "injectType" option is "styleTag": errors 1`] = `Array []`; + +exports[`loader should work when the "injectType" option is "styleTag": warnings 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +
Water
Ground
" `; -exports[`loader should work with css modules ("injectType" option is "linkTag"): errors 1`] = `Array []`; +exports[`loader should work with css modules when the "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "linkTag"): warnings 1`] = `Array []`; +exports[`loader should work with css modules when the "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "styleTag"): DOM 1`] = ` +exports[`loader should work with css modules when the "injectType" option is "lazyStyleTag": DOM 1`] = ` " style-loader test @@ -269,11 +480,57 @@ exports[`loader should work with css modules ("injectType" option is "styleTag")
Water
Ground
" `; -exports[`loader should work with css modules ("injectType" option is "styleTag"): errors 1`] = `Array []`; +exports[`loader should work with css modules when the "injectType" option is "lazyStyleTag": errors 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "styleTag"): warnings 1`] = `Array []`; +exports[`loader should work with css modules when the "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "useableStyleTag"): DOM 1`] = ` +exports[`loader should work with css modules when the "injectType" option is "linkTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +
Water
Ground
" +`; + +exports[`loader should work with css modules when the "injectType" option is "linkTag": errors 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "linkTag": warnings 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "singletonStyleTag": DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +
Water
Ground
" +`; + +exports[`loader should work with css modules when the "injectType" option is "singletonStyleTag": errors 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "styleTag": DOM 1`] = ` " style-loader test @@ -297,6 +554,30 @@ exports[`loader should work with css modules ("injectType" option is "useableSty
Water
Ground
" `; -exports[`loader should work with css modules ("injectType" option is "useableStyleTag"): errors 1`] = `Array []`; +exports[`loader should work with css modules when the "injectType" option is "styleTag": errors 1`] = `Array []`; + +exports[`loader should work with css modules when the "injectType" option is "styleTag": warnings 1`] = `Array []`; + +exports[`loader should work: DOM 1`] = ` +" + style-loader test + + + +

Body

+
+ + + +" +`; + +exports[`loader should work: errors 1`] = `Array []`; -exports[`loader should work with css modules ("injectType" option is "useableStyleTag"): warnings 1`] = `Array []`; +exports[`loader should work: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/singleton-option.test.js.snap b/test/__snapshots__/singleton-option.test.js.snap deleted file mode 100644 index 10b7c7d1..00000000 --- a/test/__snapshots__/singleton-option.test.js.snap +++ /dev/null @@ -1,73 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`singleton option false: DOM 1`] = ` -" - style-loader test - - - -

Body

-
- - - -" -`; - -exports[`singleton option false: errors 1`] = `Array []`; - -exports[`singleton option false: warnings 1`] = `Array []`; - -exports[`singleton option not specified: DOM 1`] = ` -" - style-loader test - - - -

Body

-
- - - -" -`; - -exports[`singleton option not specified: errors 1`] = `Array []`; - -exports[`singleton option not specified: warnings 1`] = `Array []`; - -exports[`singleton option true: DOM 1`] = ` -" - style-loader test - - - -

Body

-
- - - -" -`; - -exports[`singleton option true: errors 1`] = `Array []`; - -exports[`singleton option true: warnings 1`] = `Array []`; diff --git a/test/__snapshots__/validate-options.test.js.snap b/test/__snapshots__/validate-options.test.js.snap index bf7d3744..00a77586 100644 --- a/test/__snapshots__/validate-options.test.js.snap +++ b/test/__snapshots__/validate-options.test.js.snap @@ -2,8 +2,9 @@ exports[`validate options 1`] = ` "Invalid options object. Style Loader has been initialised using an options object that does not match the API schema. - - options.base should be a number. - -> Set module ID base for DLLPlugin (https://github.com/webpack-contrib/style-loader#base)." + - options.injectType should be one of these: + \\"styleTag\\" | \\"singletonStyleTag\\" | \\"lazyStyleTag\\" | \\"lazySingletonStyleTag\\" | \\"linkTag\\" + -> Allows to setup how styles will be injected in DOM." `; exports[`validate options 2`] = ` @@ -31,13 +32,7 @@ exports[`validate options 4`] = ` `; exports[`validate options 5`] = ` -"Invalid options object. Style Loader has been initialised using an options object that does not match the API schema. - - options.singleton should be a boolean. - -> Reuses a single element, instead of adding/removing individual elements for each required module (https://github.com/webpack-contrib/style-loader#singleton)." -`; - -exports[`validate options 6`] = ` "Invalid options object. Style Loader has been initialised using an options object that does not match the API schema. - options has an unknown property 'unknown'. These properties are valid: - object { base?, attributes?, insertAt?, insertInto?, singleton? }" + object { base?, injectType?, attributes?, insertAt?, insertInto? }" `; diff --git a/test/attributes-option.test.js b/test/attributes-option.test.js index c3a477db..65228082 100644 --- a/test/attributes-option.test.js +++ b/test/attributes-option.test.js @@ -1,21 +1,27 @@ -import compile from './helpers/compiler'; -import runTestInJsdom from './helpers/runTestInJsdom'; +import { compile, getTestId, runTestInJsdom } from './helpers'; describe('attributes option', () => { - const injectTypes = ['styleTag', 'useableStyleTag', 'linkTag']; + const injectTypes = [ + 'styleTag', + 'singletonStyleTag', + 'lazyStyleTag', + 'lazySingletonStyleTag', + 'linkTag', + ]; injectTypes.forEach((injectType) => { - it(`should add attributes to tag ("injectType" option is "${injectType}")`, async () => { + it(`should add attributes to tag when the "injectType" option is "${injectType}"`, async () => { expect.assertions(3); - const testId = - injectType === 'useableStyleTag' ? './useable.js' : './simple.js'; + const testId = getTestId('simple.js', injectType); const stats = await compile(testId, { loader: { - injectType, options: { + injectType, attributes: { - id: 'style-tag-id', + type: 'text/css', + foo: 'bar', + 'data-id': 'style-tag-id', }, }, }, @@ -29,20 +35,12 @@ describe('attributes option', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should override/add default type attribute to tag ("injectType" option is "${injectType}")`, async () => { + it(`should add nonce attribute when "injectType" option is "${injectType}"`, async () => { expect.assertions(3); - const testId = - injectType === 'useableStyleTag' ? './useable.js' : './simple.js'; + const testId = getTestId('nonce-require.js', injectType); const stats = await compile(testId, { - loader: { - injectType, - options: { - attributes: { - type: 'text/less', - }, - }, - }, + loader: { options: { injectType } }, }); runTestInJsdom(stats, (dom) => { @@ -52,33 +50,21 @@ describe('attributes option', () => { expect(stats.compilation.warnings).toMatchSnapshot('warnings'); expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - }); - - it('should add nonce attribute', async () => { - expect.assertions(3); - - const testId = './nonce-require.js'; - const stats = await compile(testId); - - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); - }); - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); + it(`should add nonce attribute when "injectType" option is "${injectType}" #2`, async () => { + expect.assertions(3); - it('should add nonce attribute #2', async () => { - expect.assertions(3); + const testId = getTestId('nonce-import.js', injectType); + const stats = await compile(testId, { + loader: { options: { injectType } }, + }); - const testId = './nonce-import.js'; - const stats = await compile(testId); + runTestInJsdom(stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot('DOM'); + }); - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); }); }); diff --git a/test/fixtures/useable-css-modules.js b/test/fixtures/lazy-css-modules.js similarity index 100% rename from test/fixtures/useable-css-modules.js rename to test/fixtures/lazy-css-modules.js diff --git a/test/fixtures/useable-negative-refs.js b/test/fixtures/lazy-negative-refs.js similarity index 100% rename from test/fixtures/useable-negative-refs.js rename to test/fixtures/lazy-negative-refs.js diff --git a/test/fixtures/lazy-nonce-import.js b/test/fixtures/lazy-nonce-import.js new file mode 100644 index 00000000..834c32ce --- /dev/null +++ b/test/fixtures/lazy-nonce-import.js @@ -0,0 +1,6 @@ +import './create-nonce'; +import styles from './style.css'; + +styles.use(); + + diff --git a/test/fixtures/lazy-nonce-require.js b/test/fixtures/lazy-nonce-require.js new file mode 100644 index 00000000..6bcce77a --- /dev/null +++ b/test/fixtures/lazy-nonce-require.js @@ -0,0 +1,7 @@ +__webpack_nonce__ = '12345678'; + +const styles = require('./style.css'); + +styles.use(); + + diff --git a/test/fixtures/useable.js b/test/fixtures/lazy-simple.js similarity index 87% rename from test/fixtures/useable.js rename to test/fixtures/lazy-simple.js index 519e0384..88e0f8fc 100644 --- a/test/fixtures/useable.js +++ b/test/fixtures/lazy-simple.js @@ -3,4 +3,3 @@ import styleOther from './style-other.css'; style.use(); styleOther.use(); -style.unuse(); diff --git a/test/fixtures/simple.js b/test/fixtures/simple.js index aa3357bf..9784c57c 100644 --- a/test/fixtures/simple.js +++ b/test/fixtures/simple.js @@ -1 +1,2 @@ import './style.css'; +import './style-other.css'; diff --git a/test/helpers/compiler.js b/test/helpers/compiler.js index 70e641c6..edbd69c5 100644 --- a/test/helpers/compiler.js +++ b/test/helpers/compiler.js @@ -8,47 +8,31 @@ import path from 'path'; import webpack from 'webpack'; import MemoryFS from 'memory-fs'; -function getLoaderByInjectType(injectType) { - // eslint-disable-next-line default-case - switch (injectType) { - case 'styleTag': - return path.resolve(__dirname, '../../src'); - case 'useableStyleTag': - return path.resolve(__dirname, '../../src/useable-loader.js'); - case 'linkTag': - return path.resolve(__dirname, '../../src/url-loader.js'); - } - - return path.join(__dirname, '../../src'); -} - -function getUse(config) { +const module = (config) => { const shouldUseFileLoader = config.loader && - config.loader.injectType && - config.loader.injectType === 'linkTag'; + config.loader.options && + config.loader.options.injectType === 'linkTag'; - return [ - { - loader: getLoaderByInjectType(config.loader && config.loader.injectType), - options: (config.loader && config.loader.options) || {}, - }, - shouldUseFileLoader ? { loader: 'file-loader' } : false, - { - loader: 'css-loader', - options: (config.cssLoader && config.cssLoader.options) || {}, - }, - ].filter(Boolean); -} - -const module = (config) => { return { rules: config.rules ? config.rules : [ { test: (config.loader && config.loader.test) || /\.css$/i, - use: getUse(config), + use: [ + { + loader: path.join(__dirname, '../../src'), + options: (config.loader && config.loader.options) || {}, + }, + shouldUseFileLoader + ? { loader: 'file-loader' } + : { + loader: 'css-loader', + options: + (config.cssLoader && config.cssLoader.options) || {}, + }, + ], }, ], }; diff --git a/test/helpers/getTestId.js b/test/helpers/getTestId.js new file mode 100644 index 00000000..7f6489a3 --- /dev/null +++ b/test/helpers/getTestId.js @@ -0,0 +1,7 @@ +function getTestId(testId, injectType) { + const isLazy = injectType && injectType.toLowerCase().includes('lazy'); + + return `./${isLazy ? 'lazy-' : ''}${testId}`; +} + +export default getTestId; diff --git a/test/helpers/index.js b/test/helpers/index.js new file mode 100644 index 00000000..6b078c24 --- /dev/null +++ b/test/helpers/index.js @@ -0,0 +1,5 @@ +import compile from './compiler'; +import getTestId from './getTestId'; +import runTestInJsdom from './runTestInJsdom'; + +export { compile, getTestId, runTestInJsdom }; diff --git a/test/injectType-option.test.js b/test/injectType-option.test.js new file mode 100644 index 00000000..7e6daa1a --- /dev/null +++ b/test/injectType-option.test.js @@ -0,0 +1,31 @@ +/* eslint-env browser */ + +import { compile, getTestId, runTestInJsdom } from './helpers'; + +describe('injectType option', () => { + const injectTypes = [ + 'styleTag', + 'singletonStyleTag', + 'lazyStyleTag', + 'lazySingletonStyleTag', + 'linkTag', + ]; + + injectTypes.forEach((injectType) => { + it(`should work when the "injectType" option is "${injectType}"`, async () => { + expect.assertions(3); + + const testId = getTestId('simple.js', injectType); + const stats = await compile(testId, { + loader: { options: { injectType } }, + }); + + runTestInJsdom(stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot('DOM'); + }); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + }); +}); diff --git a/test/insert-option.test.js b/test/insert-option.test.js index 49def88a..3313689c 100644 --- a/test/insert-option.test.js +++ b/test/insert-option.test.js @@ -1,13 +1,12 @@ /* eslint-env browser */ -import compile from './helpers/compiler'; -import runTestInJsdom from './helpers/runTestInJsdom'; +import { compile, runTestInJsdom } from './helpers'; describe('insert option', () => { it('should insert styles in bottom when not specified', async () => { expect.assertions(3); const testId = './simple.js'; - const stats = await compile(testId, {}); + const stats = await compile(testId); runTestInJsdom(stats, (dom) => { expect(dom.serialize()).toMatchSnapshot('DOM'); diff --git a/test/loader.test.js b/test/loader.test.js index e82f3362..965e8fde 100644 --- a/test/loader.test.js +++ b/test/loader.test.js @@ -2,19 +2,37 @@ import webpack from 'webpack'; -import compile from './helpers/compiler'; -import runTestInJsdom from './helpers/runTestInJsdom'; +import { compile, getTestId, runTestInJsdom } from './helpers'; describe('loader', () => { - const injectTypes = ['styleTag', 'useableStyleTag', 'linkTag']; + const injectTypes = [ + 'styleTag', + 'singletonStyleTag', + 'lazyStyleTag', + 'lazySingletonStyleTag', + 'linkTag', + ]; + + it(`should work`, async () => { + const testId = './simple.js'; + const stats = await compile(testId); + + runTestInJsdom(stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot('DOM'); + }); + + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); injectTypes.forEach((injectType) => { - expect.assertions(3); + it(`should work when the "injectType" option is "${injectType}"`, async () => { + expect.assertions(3); - it(`should work ("injectType" option is "${injectType}")`, async () => { - const testId = - injectType === 'useableStyleTag' ? './useable.js' : './simple.js'; - const stats = await compile(testId, { loader: { injectType } }); + const testId = getTestId('simple.js', injectType); + const stats = await compile(testId, { + loader: { options: { injectType } }, + }); runTestInJsdom(stats, (dom) => { expect(dom.serialize()).toMatchSnapshot('DOM'); @@ -24,15 +42,12 @@ describe('loader', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should work with css modules ("injectType" option is "${injectType}")`, async () => { + it(`should work with css modules when the "injectType" option is "${injectType}"`, async () => { expect.assertions(3); - const testId = - injectType === 'useableStyleTag' - ? './useable-css-modules.js' - : './css-modules.js'; + const testId = getTestId('css-modules.js', injectType); const stats = await compile(testId, { - loader: { injectType }, + loader: { options: { injectType } }, cssLoader: { options: { modules: { localIdentName: '[name]-[local]_[hash:base64:7]' }, @@ -48,9 +63,13 @@ describe('loader', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should not inject hmr code without HotModuleReplacementPlugin ("injectType" option is "${injectType}")`, async () => { + it(`should not inject hmr code without HotModuleReplacementPlugin when the "injectType" option is "${injectType}"`, async () => { + expect.assertions(4); + const testId = './hot.js'; - const stats = await compile(testId, { loader: { injectType } }); + const stats = await compile(testId, { + loader: { options: { injectType } }, + }); runTestInJsdom(stats, (dom) => { expect(dom.window.hotApi).not.toBeDefined(); @@ -64,13 +83,13 @@ describe('loader', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should inject hmr code with HotModuleReplacementPlugin ("injectType" option is "${injectType}")`, async () => { + it(`should inject hmr code with HotModuleReplacementPlugin when the "injectType" option is "${injectType}"`, async () => { expect.assertions(4); const testId = './hot.js'; const stats = await compile(testId, { plugins: [new webpack.HotModuleReplacementPlugin()], - loader: { injectType }, + loader: { options: { injectType } }, }); runTestInJsdom(stats, (dom) => { @@ -85,14 +104,13 @@ describe('loader', () => { expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - it(`should not generate source maps when previous loader don't emit them ("injectType" option is "${injectType}")`, async () => { + it(`should not generate source maps when previous loader don't emit them when the "injectType" option is "${injectType}"`, async () => { expect.assertions(3); - const testId = - injectType === 'useableStyleTag' ? './useable.js' : './simple.js'; + const testId = getTestId('simple.js', injectType); const stats = await compile(testId, { devtool: 'source-map', - loader: { injectType }, + loader: { options: { injectType } }, }); runTestInJsdom(stats, (dom) => { @@ -104,19 +122,14 @@ describe('loader', () => { }); // `linkTag` doesn't generate source maps, original source should contains them - it(`should generate source maps when previous loader emit them ("injectType" option is "${injectType}")`, async () => { + it(`should generate source maps when previous loader emit them when the "injectType" option is "${injectType}"`, async () => { expect.assertions(3); - const testId = - injectType === 'useableStyleTag' ? './useable.js' : './simple.js'; + const testId = getTestId('simple.js', injectType); const stats = await compile(testId, { devtool: 'source-map', - loader: { injectType }, - cssLoader: { - options: { - sourceMap: true, - }, - }, + loader: { options: { injectType } }, + cssLoader: { options: { sourceMap: true } }, }); runTestInJsdom(stats, (dom) => { @@ -126,21 +139,23 @@ describe('loader', () => { expect(stats.compilation.warnings).toMatchSnapshot('warnings'); expect(stats.compilation.errors).toMatchSnapshot('errors'); }); - }); - it('should work for useable inject type and negative ref', async () => { - expect.assertions(3); + if (['lazyStyleTag', 'lazySingletonStyleTag'].includes(injectType)) { + it(`should work when ref is negative when the "injectType" option is "${injectType}")`, async () => { + expect.assertions(3); - const testId = './useable-negative-refs.js'; - const stats = await compile(testId, { - loader: { injectType: 'useableStyleTag' }, - }); + const testId = './lazy-negative-refs.js'; + const stats = await compile(testId, { + loader: { options: { injectType } }, + }); - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); - }); + runTestInJsdom(stats, (dom) => { + expect(dom.serialize()).toMatchSnapshot('DOM'); + }); - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); + expect(stats.compilation.warnings).toMatchSnapshot('warnings'); + expect(stats.compilation.errors).toMatchSnapshot('errors'); + }); + } }); }); diff --git a/test/manual/webpack.config.js b/test/manual/webpack.config.js index 828f7c2b..b9edcbc7 100644 --- a/test/manual/webpack.config.js +++ b/test/manual/webpack.config.js @@ -31,7 +31,8 @@ module.exports = { test: /\.lazy\.css$/i, use: [ { - loader: require.resolve('../../dist/useable-loader.js'), + loader: require.resolve('../../dist/index.js'), + options: { injectType: 'lazyStyleTag' }, }, { loader: 'css-loader', @@ -45,7 +46,8 @@ module.exports = { test: /\.link\.css$/i, use: [ { - loader: require.resolve('../../dist/url-loader.js'), + loader: require.resolve('../../dist/index.js'), + options: { injectType: 'linkTag' }, }, { loader: 'file-loader', @@ -79,7 +81,8 @@ module.exports = { test: /\.lazy\.scss$/i, use: [ { - loader: require.resolve('../../dist/useable-loader.js'), + loader: require.resolve('../../dist/index.js'), + options: { injectType: 'lazyStyleTag' }, }, { loader: 'css-loader', diff --git a/test/singleton-option.test.js b/test/singleton-option.test.js deleted file mode 100644 index fd0d6940..00000000 --- a/test/singleton-option.test.js +++ /dev/null @@ -1,58 +0,0 @@ -import compile from './helpers/compiler'; -import runTestInJsdom from './helpers/runTestInJsdom'; - -describe('singleton option', () => { - it('not specified', async () => { - expect.assertions(3); - - const testId = './singleton.js'; - const stats = await compile(testId); - - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); - }); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it('false', async () => { - expect.assertions(3); - - const testId = './singleton.js'; - const stats = await compile(testId, { - loader: { - options: { - singleton: false, - }, - }, - }); - - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); - }); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); - - it('true', async () => { - expect.assertions(3); - - const testId = './singleton.js'; - const stats = await compile(testId, { - loader: { - options: { - singleton: true, - }, - }, - }); - - runTestInJsdom(stats, (dom) => { - expect(dom.serialize()).toMatchSnapshot('DOM'); - }); - - expect(stats.compilation.warnings).toMatchSnapshot('warnings'); - expect(stats.compilation.errors).toMatchSnapshot('errors'); - }); -}); diff --git a/test/validate-options.test.js b/test/validate-options.test.js index 111ac067..b5b26aee 100644 --- a/test/validate-options.test.js +++ b/test/validate-options.test.js @@ -20,8 +20,14 @@ it('validate options', () => { 'file.css' ); - expect(() => validate({ base: 1000 })).not.toThrow(); - expect(() => validate({ base: 'unknown' })).toThrowErrorMatchingSnapshot(); + expect(() => validate({ injectType: 'styleTag' })).not.toThrow(); + expect(() => validate({ injectType: 'singletonStyleTag' })).not.toThrow(); + expect(() => validate({ injectType: 'lazyStyleTag' })).not.toThrow(); + expect(() => validate({ injectType: 'lazySingletonStyleTag' })).not.toThrow(); + expect(() => validate({ injectType: 'linkTag' })).not.toThrow(); + expect(() => + validate({ injectType: 'unknown' }) + ).toThrowErrorMatchingSnapshot(); expect(() => validate({ attributes: {} })).not.toThrow(); expect(() => validate({ attributes: { id: 'id' } })).not.toThrow(); @@ -44,11 +50,5 @@ it('validate options', () => { expect(() => validate({ insertInto: 'test' })).not.toThrow(); expect(() => validate({ insertInto: true })).toThrowErrorMatchingSnapshot(); - expect(() => validate({ singleton: true })).not.toThrow(); - expect(() => validate({ singleton: false })).not.toThrow(); - expect(() => - validate({ singleton: 'unknown' }) - ).toThrowErrorMatchingSnapshot(); - expect(() => validate({ unknown: 'unknown' })).toThrowErrorMatchingSnapshot(); }); diff --git a/url.js b/url.js deleted file mode 100644 index 21a95485..00000000 --- a/url.js +++ /dev/null @@ -1,7 +0,0 @@ -// eslint-disable-next-line strict, lines-around-directive -'use strict'; - -// eslint-disable-next-line import/no-unresolved -const urlLoader = require('./dist/url-loader'); - -module.exports = urlLoader; diff --git a/useable.js b/useable.js deleted file mode 100644 index 5659d737..00000000 --- a/useable.js +++ /dev/null @@ -1,7 +0,0 @@ -// eslint-disable-next-line strict, lines-around-directive -'use strict'; - -// eslint-disable-next-line import/no-unresolved -const useableLoader = require('./dist/useable-loader'); - -module.exports = useableLoader;