Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: webpack-contrib/style-loader
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e4fa68a19d2390e265e27ec60ae928bf80a41228
Choose a base ref
...
head repository: webpack-contrib/style-loader
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 171a747acdc7bfd8cbc16391af46c59312733110
Choose a head ref

Commits on May 8, 2018

  1. Copy the full SHA
    c7d8fec View commit details

Commits on Jun 1, 2018

  1. Copy the full SHA
    fc24512 View commit details

Commits on Aug 7, 2018

  1. Copy the full SHA
    001159d View commit details
  2. Copy the full SHA
    e973fe2 View commit details

Commits on Aug 8, 2018

  1. Copy the full SHA
    1ca12ab View commit details
  2. Copy the full SHA
    4217bd1 View commit details

Commits on Aug 27, 2018

  1. Copy the full SHA
    2588aca View commit details
  2. Copy the full SHA
    da83a28 View commit details

Commits on Aug 28, 2018

  1. Copy the full SHA
    84fe908 View commit details

Commits on Sep 17, 2018

  1. Update README.md (#345)

    Usage section was rendering as "Usage Usage" class="icon-link" href="#usage">", removed the link, to make it consistent with source and rendering for css-loader for example.
    MattGurneyAMP authored and evilebottnawi committed Sep 17, 2018
    Copy the full SHA
    e821fe8 View commit details

Commits on Oct 8, 2018

  1. Copy the full SHA
    33aebed View commit details
  2. Copy the full SHA
    9561368 View commit details
  3. Copy the full SHA
    8003966 View commit details

Commits on Mar 21, 2019

  1. Copy the full SHA
    56d55b9 View commit details
  2. Copy the full SHA
    d6c4959 View commit details

Commits on Mar 25, 2019

  1. Copy the full SHA
    172f9b5 View commit details
  2. Copy the full SHA
    f993d7c View commit details

Commits on Mar 26, 2019

  1. 2
    Copy the full SHA
    81b4d18 View commit details

Commits on Apr 29, 2019

  1. Copy the full SHA
    5ddb01b View commit details

Commits on Jul 25, 2019

  1. fix: using inline style source maps (#383)

    BREAKING CHANGE: `convertToAbsoluteUrls` option was removed, you don't need this anymore
    jonathantneal authored and evilebottnawi committed Jul 25, 2019
    1
    Copy the full SHA
    84ec8e5 View commit details
  2. Copy the full SHA
    83b3635 View commit details

Commits on Jul 27, 2019

  1. Copy the full SHA
    8b36dca View commit details
  2. Copy the full SHA
    d41063d View commit details
  3. test: unit (#388)

    evilebottnawi authored Jul 27, 2019
    Copy the full SHA
    212525c View commit details

Commits on Jul 29, 2019

  1. refactor: tests (#389)

    evilebottnawi authored Jul 29, 2019
    Copy the full SHA
    dd32fad View commit details
  2. Copy the full SHA
    ae24ec2 View commit details
  3. Copy the full SHA
    c31a654 View commit details
  4. refactor: rename attrs option to attributes (#392)

    BREAKING CHANGE: `attrs` options was renamed to `attributes`
    evilebottnawi authored Jul 29, 2019
    Copy the full SHA
    b58d0fb View commit details
  5. Copy the full SHA
    ae8741a View commit details
  6. Copy the full SHA
    6170ff1 View commit details
  7. refactor: remove transform option (#395)

    BREAKING CHANGE: option `transform` was removed without replacement
    evilebottnawi authored Jul 29, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6ed5b6a View commit details
  8. refactor: code (#396)

    evilebottnawi authored Jul 29, 2019
    Copy the full SHA
    c53acda View commit details
  9. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    80ce578 View commit details

Commits on Jul 30, 2019

  1. refactor: tests (#398)

    evilebottnawi authored Jul 30, 2019
    Copy the full SHA
    31e70f3 View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b0187d6 View commit details
  3. refactor: remove hmr option (#400)

    BREAKING CHANGE: `hmr` option was removed, `webpack` automatically inject HMR code when it is required (when `HotModuleReplacementPlugin` plugin was used)
    evilebottnawi authored Jul 30, 2019
    Copy the full SHA
    72b490e View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9514c04 View commit details
  5. Copy the full SHA
    aed4b70 View commit details

Commits on Jul 31, 2019

  1. test: more (#403)

    evilebottnawi authored Jul 31, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c784f74 View commit details
  2. refactor: code (#404)

    evilebottnawi authored Jul 31, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ee17a77 View commit details
  3. refactor: removed sourceMap option (#405)

    BREAKING CHANGE: the `sourceMap` option was removed. The loader automatically inject source maps if previous loader emit them.
    evilebottnawi authored Jul 31, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c5992e4 View commit details
  4. feat: new injectType option

    BREAKING CHANGE: the `style-loader/url` and the `style-loader/useable` were removed in favor `injectType` option (look documentation). The `singleton` option was removed (look documentation about `injectType`).
    evilebottnawi authored Jul 31, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e2664e9 View commit details

Commits on Aug 1, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0395fed View commit details
  2. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    7c693d6 View commit details
  3. refactor: removed ref and unref api for useable loader (#409)

    BREAKING CHANGE: removed `ref`/`unref` api were removed for useable loader, please use `use`/`unuse` api
    evilebottnawi authored Aug 1, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b6d39f5 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    c9beb0f View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    ad82d5b View commit details
  6. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    b7ed255 View commit details

Commits on Aug 2, 2019

  1. refactor: insert option (#413)

    BREAKING CHANGE: `insertAt` and `insertInto` option was removed in favor `insert` option (please look docs and examples)
    evilebottnawi authored Aug 2, 2019
    Copy the full SHA
    0bb8ded View commit details

Commits on Aug 3, 2019

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    911b10b View commit details
Showing with 22,952 additions and 7,265 deletions.
  1. +0 −156 .circleci/config.yml
  2. +12 −0 .editorconfig
  3. +4 −0 .eslintignore
  4. +29 −0 .eslintrc.js
  5. +4 −1 .gitattributes
  6. +6 −0 .github/CODEOWNERS
  7. +160 −0 .github/CONTRIBUTING.md
  8. +1 −0 .github/FUNDING.yml
  9. +13 −12 .github/ISSUE_TEMPLATE.md
  10. +50 −0 .github/ISSUE_TEMPLATE/BUG.md
  11. +28 −0 .github/ISSUE_TEMPLATE/DOCS.md
  12. +25 −0 .github/ISSUE_TEMPLATE/FEATURE.md
  13. +27 −0 .github/ISSUE_TEMPLATE/MODIFICATION.md
  14. +8 −0 .github/ISSUE_TEMPLATE/SUPPORT.md
  15. +28 −11 .github/PULL_REQUEST_TEMPLATE.md
  16. +91 −0 .github/workflows/nodejs.yml
  17. +15 −1 .gitignore
  18. +5 −0 .prettierignore
  19. +1 −0 .prettierrc.js
  20. +135 −1 CHANGELOG.md
  21. +817 −462 README.md
  22. +34 −0 babel.config.js
  23. +3 −0 commitlint.config.js
  24. +6 −0 husky.config.js
  25. +0 −96 index.js
  26. +0 −44 lib/addStyleUrl.js
  27. +0 −380 lib/addStyles.js
  28. +0 −89 lib/urls.js
  29. +4 −0 lint-staged.config.js
  30. +0 −37 options.json
  31. +14,595 −4,902 package-lock.json
  32. +74 −33 package.json
  33. +3 −0 src/cjs.js
  34. +263 −0 src/index.js
  35. +39 −0 src/options.json
  36. +74 −0 src/runtime/injectStylesIntoLinkTag.js
  37. +293 −0 src/runtime/injectStylesIntoStyleTag.js
  38. +319 −0 test/__snapshots__/attributes-option.test.js.snap
  39. +25 −0 test/__snapshots__/base-option.test.js.snap
  40. +799 −0 test/__snapshots__/esModule-option.test.js.snap
  41. +115 −0 test/__snapshots__/injectType-option.test.js.snap
  42. +817 −0 test/__snapshots__/insert-option.test.js.snap
  43. +807 −0 test/__snapshots__/loader.test.js.snap
  44. +79 −0 test/__snapshots__/validate-options.test.js.snap
  45. +72 −0 test/attributes-option.test.js
  46. +23 −0 test/base-option.test.js
  47. +0 −515 test/basic.test.js
  48. +8 −0 test/cjs.test.js
  49. +221 −0 test/esModule-option.test.js
  50. +0 −216 test/fixUrls.test.js
  51. +1 −0 test/fixtures/create-nonce.js
  52. +3 −0 test/fixtures/css-modules-local-scoped.css
  53. +8 −0 test/fixtures/css-modules.css
  54. +17 −0 test/fixtures/css-modules.js
  55. +7 −0 test/fixtures/element.js
  56. +3 −0 test/fixtures/hot.js
  57. +19 −0 test/fixtures/lazy-css-modules.js
  58. +10 −0 test/fixtures/lazy-element.js
  59. +5 −0 test/fixtures/lazy-multiple.js
  60. +6 −0 test/fixtures/lazy-negative-refs.js
  61. +6 −0 test/fixtures/lazy-nonce-import.js
  62. +7 −0 test/fixtures/lazy-nonce-require.js
  63. +5 −0 test/fixtures/lazy-simple.js
  64. +2 −0 test/fixtures/multiple.js
  65. +3 −0 test/fixtures/nested/style.css
  66. +4 −0 test/fixtures/nonce-import.js
  67. +5 −0 test/fixtures/nonce-require.js
  68. +3 −0 test/fixtures/other-nested/style.css
  69. +2 −0 test/fixtures/simple.js
  70. +3 −0 test/fixtures/singleton-one.css
  71. +3 −0 test/fixtures/singleton-two.css
  72. +2 −0 test/fixtures/singleton.js
  73. +3 −0 test/fixtures/style-other.css
  74. +3 −0 test/fixtures/style.css
  75. +11 −0 test/helpers/compile.js
  76. +22 −0 test/helpers/execute.js
  77. +54 −0 test/helpers/getCompiler.js
  78. +7 −0 test/helpers/getEntryByInjectType.js
  79. +5 −0 test/helpers/getErrors.js
  80. +5 −0 test/helpers/getWarnings.js
  81. +23 −0 test/helpers/index.js
  82. +19 −0 test/helpers/normalizeErrors.js
  83. +23 −0 test/helpers/readAsset.js
  84. +11 −0 test/helpers/readAssets.js
  85. +44 −0 test/helpers/runInJsDom.js
  86. +37 −0 test/injectType-option.test.js
  87. +175 −0 test/insert-option.test.js
  88. +0 −3 test/insert/into.js
  89. +339 −0 test/loader.test.js
  90. +97 −0 test/manual/index.html
  91. +20 −0 test/manual/src/component.lazy.module.css
  92. +20 −0 test/manual/src/component.module.css
  93. +38 −0 test/manual/src/custom-square.js
  94. +5 −0 test/manual/src/custom-square.lazy.css
  95. +3 −0 test/manual/src/duplicate.css
  96. +116 −0 test/manual/src/index.js
  97. BIN test/manual/src/logo.png
  98. +3 −0 test/manual/src/modules/common.module.css
  99. +4 −0 test/manual/src/modules/one.module.css
  100. +5 −0 test/manual/src/modules/page.module.css
  101. +5 −0 test/manual/src/modules/toolbar.module.css
  102. +4 −0 test/manual/src/modules/two.module.css
  103. +2 −0 test/manual/src/nested.css
  104. +5 −0 test/manual/src/nested/style.css
  105. +3 −0 test/manual/src/order-1.css
  106. +3 −0 test/manual/src/order-2.css
  107. +13 −0 test/manual/src/order.css
  108. +20 −0 test/manual/src/other-style.lazy.scss
  109. +20 −0 test/manual/src/other-style.scss
  110. +16 −0 test/manual/src/style.css
  111. +16 −0 test/manual/src/style.lazy.css
  112. +11 −0 test/manual/src/style.link.css
  113. +3 −0 test/manual/src/use-unuse.lazy.css
  114. +176 −0 test/manual/webpack.config.js
  115. +45 −0 test/runtime/__snapshots__/injectStylesIntoLinkTag.test.js.snap
  116. +168 −0 test/runtime/__snapshots__/injectStylesIntoStyleTag.test.js.snap
  117. +221 −0 test/runtime/injectStylesIntoLinkTag.test.js
  118. +795 −0 test/runtime/injectStylesIntoStyleTag.test.js
  119. +0 −3 test/transforms/false.js
  120. +0 −1 test/transforms/noop.js
  121. +0 −3 test/transforms/transform.js
  122. +0 −37 test/url.test.js
  123. +0 −37 test/useable.test.js
  124. +0 −114 test/utils.js
  125. +78 −0 test/validate-options.test.js
  126. +0 −39 url.js
  127. +0 −72 useable.js
156 changes: 0 additions & 156 deletions .circleci/config.yml

This file was deleted.

12 changes: 12 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# editorconfig.org

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/coverage
/dist
/node_modules
/test/fixtures
29 changes: 29 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module.exports = {
root: true,
extends: ['@webpack-contrib/eslint-config-webpack', 'prettier'],
overrides: [
{
files: ['src/runtime/**/*.js'],
env: {
browser: true,
node: true,
},
globals: {
__webpack_nonce__: 'readonly',
},
rules: {
'no-underscore-dangle': 'off',
'no-plusplus': 'off',
'consistent-return': 'off',
'no-param-reassign': 'off',
camelcase: [
'error',
{ properties: 'never', allow: ['__webpack_nonce__'] },
],
// avoid unnecessary `babel` helpers
'prefer-destructuring': 'off',
'prefer-rest-params': 'off',
},
},
],
};
5 changes: 4 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Treats the lock file as binary & prevents conflict hell
yarn.lock -diff
yarn.lock -diff
* text=auto
package-lock.json -diff
bin/* eol=lf
6 changes: 6 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# These are the default owners for everything in
# webpack-contrib
@webpack-contrib/org-maintainers

# Add repository specific users / groups
# below here for libs that are not maintained by the org.
160 changes: 160 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Contributing in @webpack-contrib

We'd always love contributions to further improve the webpack / webpack-contrib ecosystem!
Here are the guidelines we'd like you to follow:

- [Questions and Problems](#question)
- [Issues and Bugs](#issue)
- [Feature Requests](#feature)
- [Pull Request Submission Guidelines](#submit-pr)
- [Commit Message Conventions](#commit)

## <a name="question"></a> Got a Question or Problem?

Please submit support requests and questions to StackOverflow using the tag [[webpack]](http://stackoverflow.com/tags/webpack).
StackOverflow is better suited for this kind of support though you may also inquire in [Webpack Gitter](https://gitter.im/webpack/webpack).
The issue tracker is for bug reports and feature discussions.

## <a name="issue"></a> Found an Issue or Bug?

Before you submit an issue, please search the issue tracker, maybe an issue for your problem already exists and the discussion might inform you of workarounds readily available.

We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs, we ask that you to provide a minimal reproduction scenario (github repo or failing test case). Having a live, reproducible scenario gives us a wealth of important information without going back & forth to you with additional questions like:

- version of Webpack used
- version of the loader / plugin you are creating a bug report for
- the use-case that fails

A minimal reproduce scenario allows us to quickly confirm a bug (or point out config problems) as well as confirm that we are fixing the right problem.

We will be insisting on a minimal reproduce scenario in order to save maintainers time and ultimately be able to fix more bugs. We understand that sometimes it might be hard to extract essentials bits of code from a larger code-base but we really need to isolate the problem before we can fix it.

Unfortunately, we are not able to investigate / fix bugs without a minimal reproduction, so if we don't hear back from you we are going to close an issue that doesn't have enough info to be reproduced.

## <a name="feature"></a> Feature Requests?

You can _request_ a new feature by creating an issue on Github.

If you would like to _implement_ a new feature, please submit an issue with a proposal for your work `first`, to be sure that particular makes sense for the project.

## <a name="submit-pr"></a> Pull Request Submission Guidelines

Before you submit your Pull Request (PR) consider the following guidelines:

- Search Github for an open or closed PR that relates to your submission. You don't want to duplicate effort.
- Commit your changes using a descriptive commit message that follows our [commit message conventions](#commit). Adherence to these conventions is necessary because release notes are automatically generated from these messages.
- Fill out our `Pull Request Template`. Your pull request will not be considered if it is ignored.
- Please sign the `Contributor License Agreement (CLA)` when a pull request is opened. We cannot accept your pull request without this. Make sure you sign with the primary email address associated with your local / github account.

## <a name="commit"></a> Webpack Contrib Commit Conventions

Each commit message consists of a **header**, a **body** and a **footer**. The header has a special
format that includes a **type**, a **scope** and a **subject**:

```
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
```

The **header** is mandatory and the **scope** of the header is optional.

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on GitHub as well as in various git tools.

The footer should contain a [closing reference to an issue](https://help.github.com/articles/closing-issues-via-commit-messages/) if any.

Examples:

```
docs(readme): update install instructions
```

```
fix: refer to the `entrypoint` instead of the first `module`
```

### Revert

If the commit reverts a previous commit, it should begin with `revert:`, followed by the header of the reverted commit.
In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.

### Type

Must be one of the following:

- **build**: Changes that affect the build system or external dependencies (example scopes: babel, npm)
- **chore**: Changes that fall outside of build / docs that do not effect source code (example scopes: package, defaults)
- **ci**: Changes to our CI configuration files and scripts (example scopes: circleci, travis)
- **docs**: Documentation only changes (example scopes: readme, changelog)
- **feat**: A new feature
- **fix**: A bug fix
- **perf**: A code change that improves performance
- **refactor**: A code change that neither fixes a bug nor adds a feature
- **revert**: Used when reverting a committed change
- **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons)
- **test**: Addition of or updates to Jest tests

### Scope

The scope is subjective & depends on the `type` see above. A good example would be a change to a particular class / module.

### Subject

The subject contains a succinct description of the change:

- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end

### Body

Just as in the **subject**, use the imperative, present tense: "change" not "changed" nor "changes".
The body should include the motivation for the change and contrast this with previous behavior.

### Footer

The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.

**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.

Example

```
BREAKING CHANGE: Updates to `Chunk.mapModules`.
This release is not backwards compatible with `Webpack 2.x` due to breaking changes in webpack/webpack#4764
Migration: see webpack/webpack#5225
```

## Testing Your Pull Request

You may have the need to test your changes in a real-world project or dependent
module. Thankfully, Github provides a means to do this. Add a dependency to the
`package.json` for such a project as follows:

```json
{
"devDependencies": {
"style-loader": "webpack-contrib/style-loader#{id}/head"
}
}
```

Where `{id}` is the # ID of your Pull Request.

## Contributor License Agreement

When submitting your contribution, a CLA (Contributor License Agreement) bot will come by to verify that you signed the [CLA](https://cla.js.foundation/webpack-contrib/style-loader).
If it is your first time, it will link you to the right place to sign it.
However, if you have committed your contributions using an email that is not the same as your email used on GitHub, the CLA bot can't accept your contribution.

Run `git config user.email` to see your Git email, and verify it with [your GitHub email](https://github.com/settings/emails).

## Thanks

For your interest, time, understanding, and for following this simple guide.
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
open_collective: webpack
25 changes: 13 additions & 12 deletions .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<!-- Before creating an issue please make sure you are using the latest version of style-loader. -->
<!--
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
**Do you want to request a *feature* or report a *bug*?**
<!-- Please ask questions on StackOverflow or the webpack Gitter (https://gitter.im/webpack/webpack). Questions will be closed. -->
Hey there!
**What is the current behavior?**
You arrived at this template because you felt none of the other options
matched the kind of issue you'd like to report. Please use this opportunity to
tell us about your particular type of issue so we can try to accomodate
similar issues in the future.
**If the current behavior is a bug, please provide the steps to reproduce.**
<!-- A great way to do this is to provide your configuration via a GitHub gist. -->

**What is the expected behavior?**

**If this is a feature request, what is motivation or use case for changing the behavior?**

**Please mention other relevant information such as your webpack version, Node.js version and Operating System.**
PLEASE do note, if you're using this to report an issue already covered by the
existing template types, your issue may be closed as invalid. Our issue
templates contain fields that help us help you, and without that important
info, we might as well be ice-skating uphill, carrying a wooly mammoth.
-->
50 changes: 50 additions & 0 deletions .github/ISSUE_TEMPLATE/BUG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
name: 🐛 Bug Report
about: Something went awry and you'd like to tell us about it.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- style-loader Version:

### Expected Behavior

<!-- Remove this section if not reporting a bug or modification request. -->

### Actual Behavior

<!-- Remove this section if not reporting a bug or modification request. -->

### Code

```js
// webpack.config.js
// If your code blocks are over 20 lines, please paste a link to a gist
// (https://gist.github.com).
```

```js
// additional code, HEY YO remove this block if you don't need it
```

### How Do We Reproduce?

<!--
Remove this section if not reporting a bug.
If your webpack config is over 50 lines long, please provide a URL to a repo
for your beefy 🍖 app that we can use to reproduce.
-->
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/DOCS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
name: 📚 Documentation
about: Are the docs lacking or missing something? Do they need some new 🔥 hotness? Tell us here.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

Documentation Is:

<!-- Please place an x (no spaces!) in all [ ] that apply -->

- [ ] Missing
- [ ] Needed
- [ ] Confusing
- [ ] Not Sure?

### Please Explain in Detail...

### Your Proposal for Changes
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/FEATURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: ✨ Feature Request
about: Suggest an idea for this project
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- style-loader Version:

### Feature Proposal

### Feature Use Case
27 changes: 27 additions & 0 deletions .github/ISSUE_TEMPLATE/MODIFICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: 🔧 Modification Request
about: Would you like something work differently? Have an alternative approach? This is the template for you.
---

<!--
Issues are so 🔥
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
👉🏽 Need support, advice, or help? Don't open an issue!
Head to StackOverflow or https://gitter.im/webpack/webpack.
-->

- Operating System:
- Node Version:
- NPM Version:
- webpack Version:
- style-loader Version:

### Expected Behavior / Situation

### Actual Behavior / Situation

### Modification Proposal
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/SUPPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
name: 🆘 Support, Help, and Advice
about: 👉🏽 Need support, help, or advice? Don't open an issue! Head to StackOverflow or https://gitter.im/webpack/webpack.
---

Hey there! If you need support, help, or advice then this is not the place to ask.
Please visit [StackOverflow](https://stackoverflow.com/questions/tagged/webpack)
or [the Webpack Gitter](https://gitter.im/webpack/webpack) instead.
39 changes: 28 additions & 11 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->
<!--
HOLY CRAP a Pull Request. We ❤️ those!
**What kind of change does this PR introduce?**
<!-- E.g. a bugfix, feature, refactoring, build related change, etc… -->
If you remove or skip this template, you'll make the 🐼 sad and the mighty god
of Github will appear and pile-drive the close button from a great height
while making animal noises.
**Did you add tests for your changes?**
Please place an x (no spaces!) in all [ ] that apply
-->

**If relevant, did you update the README?**
This PR contains a:

**Summary**
- [ ] **bugfix**
- [ ] new **feature**
- [ ] **code refactor**
- [ ] **test update** <!-- if bug or feature is checked, this should be too -->
- [ ] **typo fix**
- [ ] **metadata update**

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
<!-- Try to link to an open issue for more information. -->
### Motivation / Use-Case

**Does this PR introduce a breaking change?**
<!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. -->
<!--
Please explain the motivation or use-case for your change.
What existing problem does the PR solve?
If this PR addresses an issue, please link to the issue.
-->

**Other information**
### Breaking Changes

<!--
If this PR introduces a breaking change, please describe the impact and a
migration path for existing applications.
-->

### Additional Info
91 changes: 91 additions & 0 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
name: style-loader

on:
push:
branches:
- master
- next
pull_request:
branches:
- master
- next

jobs:
lint:
name: Lint - ${{ matrix.os }} - Node v${{ matrix.node-version }}

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

strategy:
matrix:
os: [ubuntu-latest]
node-version: [12.x]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ env.node-version }}

- name: Use latest NPM
run: sudo npm i -g npm

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

# - name: Security audit
# run: npm run security

- name: Check commit message
uses: wagoid/commitlint-github-action@v1

test:
name: Test - ${{ matrix.os }} - Node v${{ matrix.node-version }}, Webpack ${{ matrix.webpack-version }}

strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [8.x, 10.x, 12.x, 13.x]
webpack-version: [latest, next]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}

- name: Use latest NPM on ubuntu/macos
if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest'
run: sudo npm i -g npm

- name: Use latest NPM on windows
if: matrix.os == 'windows-latest'
run: npm i -g npm

- name: Install dependencies
run: npm ci

- name: Install webpack ${{ matrix.webpack-version }}
run: npm i webpack@${{ matrix.webpack-version }}

- name: Run tests for webpack version ${{ matrix.webpack-version }}
run: npm run test:coverage -- --ci

- name: Submit coverage data to codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
16 changes: 15 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
/node_modules
.idea/
/coverage
/coverage
logs
*.log
npm-debug.log*
.eslintcache
/dist
/local
/reports
.DS_Store
Thumbs.db
.idea
*.iml
.vscode
*.sublime-project
*.sublime-workspace
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/coverage
/dist
/node_modules
/test/fixtures
CHANGELOG.md
1 change: 1 addition & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = { singleQuote: true };
136 changes: 135 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,141 @@
# Change Log
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [1.1.4](https://github.com/webpack-contrib/style-loader/compare/v1.1.3...v1.1.4) (2020-04-15)


# Chore

* update deps


### [1.1.3](https://github.com/webpack-contrib/style-loader/compare/v1.1.2...v1.1.3) (2020-01-17)


### Bug Fixes

* injection algorithm ([#456](https://github.com/webpack-contrib/style-loader/issues/456)) ([236b243](https://github.com/webpack-contrib/style-loader/commit/236b2436fb0003eeba5f0aa33e7caf9f35d4fc7a))

### [1.1.2](https://github.com/webpack-contrib/style-loader/compare/v1.1.1...v1.1.2) (2019-12-25)


### Bug Fixes

* algorithm for importing modules ([#449](https://github.com/webpack-contrib/style-loader/issues/449)) ([91ceaf2](https://github.com/webpack-contrib/style-loader/commit/91ceaf2b7e03f065d2a8cace1b733777848d4e86))
* checking that the list of modules is an array ([#448](https://github.com/webpack-contrib/style-loader/issues/448)) ([1138ed7](https://github.com/webpack-contrib/style-loader/commit/1138ed7e04848b570a70e493b410902cfc4a9076))

### [1.1.1](https://github.com/webpack-contrib/style-loader/compare/v1.1.0...v1.1.1) (2019-12-20)


### Bug Fixes

* add empty default export for `linkTag` value ([7ee8b04](https://github.com/webpack-contrib/style-loader/commit/7ee8b04fd519847cef93052c31efa0d0012ed54e))

## [1.1.0](https://github.com/webpack-contrib/style-loader/compare/v1.0.2...v1.1.0) (2019-12-20)


### Features

* `esModule` option ([#441](https://github.com/webpack-contrib/style-loader/issues/441)) ([3415266](https://github.com/webpack-contrib/style-loader/commit/3415266f58f2be00bec1d66ae9e658437e0d0a6c))


### Bug Fixes

* order of imported styles ([#443](https://github.com/webpack-contrib/style-loader/issues/443)) ([c7d6e3a](https://github.com/webpack-contrib/style-loader/commit/c7d6e3a3fba63a76e8f342d84e00b69af92c7ebc))

### [1.0.2](https://github.com/webpack-contrib/style-loader/compare/v1.0.1...v1.0.2) (2019-12-17)


### Bug Fixes

* support ES module syntax ([#435](https://github.com/webpack-contrib/style-loader/issues/435)) ([dcbfadb](https://github.com/webpack-contrib/style-loader/commit/dcbfadb4245e7f0ce888aafc138cbac27d053915))

### [1.0.1](https://github.com/webpack-contrib/style-loader/compare/v1.0.0...v1.0.1) (2019-11-28)


### Bug Fixes

* compatibility `linkTag` with ES module syntax ([#429](https://github.com/webpack-contrib/style-loader/issues/429)) ([2cdb9c3](https://github.com/webpack-contrib/style-loader/commit/2cdb9c3f51edebec69e8b22ff43b520a5e1c679b))

## [1.0.0](https://github.com/webpack-contrib/style-loader/compare/v0.23.1...v1.0.0) (2019-08-06)


### Bug Fixes

* es3 compatibility ([#390](https://github.com/webpack-contrib/style-loader/issues/390)) ([ae24ec2](https://github.com/webpack-contrib/style-loader/commit/ae24ec2))
* restore original hot reloading behaviour for locals ([#419](https://github.com/webpack-contrib/style-loader/issues/419)) ([f026429](https://github.com/webpack-contrib/style-loader/commit/f026429))
* better handle source maps ([#383](https://github.com/webpack-contrib/style-loader/issues/383)) ([84ec8e5](https://github.com/webpack-contrib/style-loader/commit/84ec8e5))


### Features

* new `injectType` option ([e2664e9](https://github.com/webpack-contrib/style-loader/commit/e2664e9))
* remove type `text/css` from style and link element ([#399](https://github.com/webpack-contrib/style-loader/issues/399)) ([b0187d6](https://github.com/webpack-contrib/style-loader/commit/b0187d6))


### BREAKING CHANGES

* minimum required Node.js version is `8.9.0`
* minimum required `wepback` version is `4.0.0`
* the `convertToAbsoluteUrls` option was removed, you don't need this anymore
* the `attrs` option was renamed to the `attributes` option
* the `transform` option was removed without replacement
* the `hmr` option was removed, `webpack` automatically inject HMR code when it is required (when the `HotModuleReplacementPlugin` plugin was used)
* the `sourceMap` option was removed. The loader automatically inject source maps if the previous loader emit them
* the `ref`/`unref` api methods were removed for `useable` loader, please use the `use`/`unuse` api methods
* the `style-loader/url` loader was removed in favor `injectType` option (look the documentation about the `injectType` option)
* the `style-loader/useable` loader was removed in favor `injectType` option (look the documentation about the `injectType` option)
* the `singleton` option was removed (look documentation about the `injectType` option)
* the `insertAt` option was removed in favor the `insert` option (look the documentation about the `insert` option and examples)
* the `insertInto` options was removed in favor the `insert` option (look the documentation about the `insert` option and examples)


<a name="0.23.1"></a>
## [0.23.1](https://github.com/webpack-contrib/style-loader/compare/v0.23.0...v0.23.1) (2018-10-08)


### Bug Fixes

* **addStyles:** support exports of transpiled transforms (`options.transform`) ([#333](https://github.com/webpack-contrib/style-loader/issues/333)) ([33aebed](https://github.com/webpack-contrib/style-loader/commit/33aebed))



<a name="0.23.0"></a>
# [0.23.0](https://github.com/webpack-contrib/style-loader/compare/v0.22.1...v0.23.0) (2018-08-27)


### Features

* **useable:** add `insertInto` support (`options.insertInto`) ([#341](https://github.com/webpack-contrib/style-loader/issues/341)) ([2588aca](https://github.com/webpack-contrib/style-loader/commit/2588aca))



<a name="0.22.1"></a>
## [0.22.1](https://github.com/webpack-contrib/style-loader/compare/v0.22.0...v0.22.1) (2018-08-08)


### Bug Fixes

* **addStyles:** use `var` instead of `const` (IE fix) ([#338](https://github.com/webpack-contrib/style-loader/issues/338)) ([1ca12ab](https://github.com/webpack-contrib/style-loader/commit/1ca12ab))



<a name="0.22.0"></a>
# [0.22.0](https://github.com/webpack-contrib/style-loader/compare/v0.21.0...v0.22.0) (2018-08-07)


### Bug Fixes

* insertInto and insertAt collaboration ([#325](https://github.com/webpack-contrib/style-loader/issues/325)) ([c7d8fec](https://github.com/webpack-contrib/style-loader/commit/c7d8fec))


### Features

* add support for __webpack_nonce__ ([#319](https://github.com/webpack-contrib/style-loader/issues/319)) ([fc24512](https://github.com/webpack-contrib/style-loader/commit/fc24512))



<a name="0.21.0"></a>
# [0.21.0](https://github.com/webpack-contrib/style-loader/compare/v0.20.3...v0.21.0) (2018-04-18)

1,279 changes: 817 additions & 462 deletions README.md

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const MIN_BABEL_VERSION = 7;

module.exports = (api) => {
api.assertVersion(MIN_BABEL_VERSION);
api.cache(true);

return {
presets: [
[
'@babel/preset-env',
{
targets: {
node: '8.9.0',
},
},
],
],
overrides: [
{
test: './src/runtime',
presets: [
[
'@babel/preset-env',
{
targets: {
node: '0.12',
},
},
],
],
},
],
};
};
3 changes: 3 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['@commitlint/config-conventional'],
};
6 changes: 6 additions & 0 deletions husky.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
hooks: {
'pre-commit': 'lint-staged',
'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
},
};
96 changes: 0 additions & 96 deletions index.js

This file was deleted.

44 changes: 0 additions & 44 deletions lib/addStyleUrl.js

This file was deleted.

380 changes: 0 additions & 380 deletions lib/addStyles.js

This file was deleted.

89 changes: 0 additions & 89 deletions lib/urls.js

This file was deleted.

4 changes: 4 additions & 0 deletions lint-staged.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
'*.js': ['prettier --write', 'eslint --fix'],
'*.{json,md,yml,css,ts}': ['prettier --write'],
};
37 changes: 0 additions & 37 deletions options.json

This file was deleted.

19,497 changes: 14,595 additions & 4,902 deletions package-lock.json

Large diffs are not rendered by default.

107 changes: 74 additions & 33 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,45 +1,86 @@
{
"name": "style-loader",
"version": "0.21.0",
"author": "Tobias Koppers @sokra",
"version": "1.1.4",
"description": "style loader module for webpack",
"license": "MIT",
"repository": "webpack-contrib/style-loader",
"author": "Tobias Koppers @sokra",
"homepage": "https://github.com/webpack-contrib/style-loader",
"bugs": "https://github.com/webpack-contrib/style-loader/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"main": "dist/cjs.js",
"engines": {
"node": ">= 0.12.0"
"node": ">= 8.9.0"
},
"scripts": {
"start": "npm run build -- -w",
"clean": "del-cli dist",
"validate:runtime": "es-check es3 \"dist/runtime/**/*.js\"",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --copy-files",
"postbuild": "npm run validate:runtime",
"commitlint": "commitlint --from=master",
"security": "npm audit",
"lint:prettier": "prettier --list-different .",
"lint:js": "eslint --cache .",
"lint": "npm-run-all -l -p \"lint:**\"",
"test:only": "cross-env NODE_ENV=test jest",
"test:watch": "npm run test:only -- --watch",
"test:coverage": "npm run test:only -- --collectCoverageFrom=\"src/**/*.js\" --coverage",
"test:manual": "npm run build && webpack-dev-server test/manual/src/index.js --open --config test/manual/webpack.config.js",
"pretest": "npm run lint",
"test": "npm run test:coverage",
"prepare": "npm run build",
"release": "standard-version",
"defaults": "webpack-defaults"
},
"main": "index.js",
"files": [
"lib",
"url.js",
"index.js",
"useable.js",
"options.json"
"dist"
],
"peerDependencies": {
"webpack": "^4.0.0 || ^5.0.0"
},
"dependencies": {
"loader-utils": "^1.1.0",
"schema-utils": "^0.4.5"
"loader-utils": "^2.0.0",
"schema-utils": "^2.6.5"
},
"devDependencies": {
"css-loader": "^0.28.0",
"file-loader": "^1.0.0",
"istanbul": "^0.4.5",
"jsdom": "^9.0.0",
"memory-fs": "^0.4.0",
"mocha": "^4.0.0",
"nsp": "^3.2.1",
"sinon": "^4.0.0",
"standard-version": "^4.0.0",
"webpack": "^2.0.0"
},
"scripts": {
"test": "mocha",
"test:coverage": "istanbul cover node_modules/mocha/bin/_mocha",
"ci:test": "npm run test",
"ci:coverage": "npm run test:coverage",
"release": "standard-version",
"security": "nsp check"
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@webpack-contrib/defaults": "^6.3.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^25.3.0",
"cross-env": "^7.0.2",
"css-loader": "^3.5.2",
"del": "^5.1.0",
"del-cli": "^3.0.0",
"es-check": "^5.1.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.1",
"eslint-plugin-import": "^2.20.2",
"file-loader": "^6.0.0",
"husky": "^4.2.5",
"jest": "^25.3.0",
"jsdom": "^15.2.1",
"lint-staged": "^10.1.3",
"memfs": "^3.1.2",
"npm-run-all": "^4.1.5",
"prettier": "^2.0.4",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"semver": "^7.3.2",
"standard-version": "^7.1.0",
"webpack": "^4.42.1",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"repository": "https://github.com/webpack-contrib/style-loader.git",
"bugs": "https://github.com/webpack-contrib/style-loader/issues",
"homepage": "https://github.com/webpack-contrib/style-loader#readme",
"license": "MIT"
"keywords": [
"webpack"
]
}
3 changes: 3 additions & 0 deletions src/cjs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const loader = require('./index');

module.exports = loader.default;
263 changes: 263 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
import path from 'path';

import loaderUtils from 'loader-utils';
import validateOptions from 'schema-utils';

import schema from './options.json';

const loaderApi = () => {};

loaderApi.pitch = function loader(request) {
const options = loaderUtils.getOptions(this);

validateOptions(schema, options, {
name: 'Style Loader',
baseDataPath: 'options',
});

const insert =
typeof options.insert === 'undefined'
? '"head"'
: typeof options.insert === 'string'
? JSON.stringify(options.insert)
: options.insert.toString();
const injectType = options.injectType || 'styleTag';
const esModule =
typeof options.esModule !== 'undefined' ? options.esModule : false;

delete options.esModule;

switch (injectType) {
case 'linkTag': {
const hmrCode = this.hot
? `
if (module.hot) {
module.hot.accept(
${loaderUtils.stringifyRequest(this, `!!${request}`)},
function() {
${
esModule
? `update(content);`
: `var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
update(newContent);`
}
}
);
module.hot.dispose(function() {
update();
});
}`
: '';

return `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoLinkTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;`
}
var options = ${JSON.stringify(options)};
options.insert = ${insert};
var update = api(content, options);
${hmrCode}
${esModule ? `export default {}` : ''}`;
}

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) {
exported.use();
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 `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.id, content, '']];
}`
}
var refs = 0;
var dispose;
var options = ${JSON.stringify(options)};
options.insert = ${insert};
options.singleton = ${isSingleton};
var exported = {};
if (content.locals) {
exported.locals = content.locals;
}
exported.use = function() {
if (!(refs++)) {
dispose = api(content, options);
}
return exported;
};
exported.unuse = function() {
if (refs > 0 && !--refs) {
dispose();
dispose = null;
}
};
${hmrCode}
${esModule ? 'export default' : 'module.exports ='} exported;`;
}

case 'styleTag':
case 'singletonStyleTag':
default: {
const isSingleton = injectType === 'singletonStyleTag';

const hmrCode = this.hot
? `
if (module.hot) {
if (!content.locals) {
module.hot.accept(
${loaderUtils.stringifyRequest(this, `!!${request}`)},
function () {
${
esModule
? `update(content);`
: `var newContent = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
newContent = newContent.__esModule ? newContent.default : newContent;
if (typeof newContent === 'string') {
newContent = [[module.id, newContent, '']];
}
update(newContent);`
}
}
)
}
module.hot.dispose(function() {
update();
});
}`
: '';

return `${
esModule
? `import api from ${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)};
import content from ${loaderUtils.stringifyRequest(
this,
`!!${request}`
)};
var clonedContent = content;`
: `var api = require(${loaderUtils.stringifyRequest(
this,
`!${path.join(__dirname, 'runtime/injectStylesIntoStyleTag.js')}`
)});
var content = require(${loaderUtils.stringifyRequest(
this,
`!!${request}`
)});
content = content.__esModule ? content.default : content;
if (typeof content === 'string') {
content = [[module.id, content, '']];
}`
}
var options = ${JSON.stringify(options)};
options.insert = ${insert};
options.singleton = ${isSingleton};
var update = api(content, options);
var exported = content.locals ? content.locals : {};
${hmrCode}
${esModule ? 'export default' : 'module.exports ='} exported;`;
}
}
};

export default loaderApi;
39 changes: 39 additions & 0 deletions src/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"type": "object",
"properties": {
"injectType": {
"description": "Allows to setup how styles will be injected into DOM (https://github.com/webpack-contrib/style-loader#injecttype).",
"enum": [
"styleTag",
"singletonStyleTag",
"lazyStyleTag",
"lazySingletonStyleTag",
"linkTag"
]
},
"attributes": {
"description": "Adds custom attributes to tag (https://github.com/webpack-contrib/style-loader#attributes).",
"type": "object"
},
"insert": {
"description": "Inserts `<style>`/`<link>` at the given position (https://github.com/webpack-contrib/style-loader#insert).",
"anyOf": [
{
"type": "string"
},
{
"instanceof": "Function"
}
]
},
"base": {
"description": "Sets module ID base for DLLPlugin (https://github.com/webpack-contrib/style-loader#base).",
"type": "number"
},
"esModule": {
"description": "Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule).",
"type": "boolean"
}
},
"additionalProperties": false
}
74 changes: 74 additions & 0 deletions src/runtime/injectStylesIntoLinkTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const getTarget = (function getTarget() {
const memo = {};

return function memorize(target) {
if (typeof memo[target] === 'undefined') {
let styleTarget = document.querySelector(target);

// Special case to return head of iframe instead of iframe itself
if (
window.HTMLIFrameElement &&
styleTarget instanceof window.HTMLIFrameElement
) {
try {
// This will throw an exception if access to iframe is blocked
// due to cross-origin restrictions
styleTarget = styleTarget.contentDocument.head;
} catch (e) {
// istanbul ignore next
styleTarget = null;
}
}

memo[target] = styleTarget;
}

return memo[target];
};
})();

module.exports = (url, options) => {
options = options || {};
options.attributes =
typeof options.attributes === 'object' ? options.attributes : {};

if (typeof options.attributes.nonce === 'undefined') {
const nonce =
typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;

if (nonce) {
options.attributes.nonce = nonce;
}
}

const link = document.createElement('link');

link.rel = 'stylesheet';
link.href = url;

Object.keys(options.attributes).forEach((key) => {
link.setAttribute(key, options.attributes[key]);
});

if (typeof options.insert === 'function') {
options.insert(link);
} else {
const target = getTarget(options.insert || 'head');

if (!target) {
throw new Error(
"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."
);
}

target.appendChild(link);
}

return (newUrl) => {
if (typeof newUrl === 'string') {
link.href = newUrl;
} else {
link.parentNode.removeChild(link);
}
};
};
293 changes: 293 additions & 0 deletions src/runtime/injectStylesIntoStyleTag.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
const isOldIE = (function isOldIE() {
let memo;

return function memorize() {
if (typeof memo === 'undefined') {
// Test for IE <= 9 as proposed by Browserhacks
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
// Tests for existence of standard globals is to allow style-loader
// to operate correctly into non-standard environments
// @see https://github.com/webpack-contrib/style-loader/issues/177
memo = Boolean(window && document && document.all && !window.atob);
}

return memo;
};
})();

const getTarget = (function getTarget() {
const memo = {};

return function memorize(target) {
if (typeof memo[target] === 'undefined') {
let styleTarget = document.querySelector(target);

// Special case to return head of iframe instead of iframe itself
if (
window.HTMLIFrameElement &&
styleTarget instanceof window.HTMLIFrameElement
) {
try {
// This will throw an exception if access to iframe is blocked
// due to cross-origin restrictions
styleTarget = styleTarget.contentDocument.head;
} catch (e) {
// istanbul ignore next
styleTarget = null;
}
}

memo[target] = styleTarget;
}

return memo[target];
};
})();

const stylesInDom = [];

function getIndexByIdentifier(identifier) {
let result = -1;

for (let i = 0; i < stylesInDom.length; i++) {
if (stylesInDom[i].identifier === identifier) {
result = i;
break;
}
}

return result;
}

function modulesToDom(list, options) {
const idCountMap = {};
const identifiers = [];

for (let i = 0; i < list.length; i++) {
const item = list[i];
const id = options.base ? item[0] + options.base : item[0];
const count = idCountMap[id] || 0;
const identifier = `${id} ${count}`;

idCountMap[id] = count + 1;

const index = getIndexByIdentifier(identifier);
const obj = {
css: item[1],
media: item[2],
sourceMap: item[3],
};

if (index !== -1) {
stylesInDom[index].references++;
stylesInDom[index].updater(obj);
} else {
stylesInDom.push({
identifier,
updater: addStyle(obj, options),
references: 1,
});
}

identifiers.push(identifier);
}

return identifiers;
}

function insertStyleElement(options) {
const style = document.createElement('style');
const attributes = options.attributes || {};

if (typeof attributes.nonce === 'undefined') {
const nonce =
typeof __webpack_nonce__ !== 'undefined' ? __webpack_nonce__ : null;

if (nonce) {
attributes.nonce = nonce;
}
}

Object.keys(attributes).forEach((key) => {
style.setAttribute(key, attributes[key]);
});

if (typeof options.insert === 'function') {
options.insert(style);
} else {
const target = getTarget(options.insert || 'head');

if (!target) {
throw new Error(
"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."
);
}

target.appendChild(style);
}

return style;
}

function removeStyleElement(style) {
// istanbul ignore if
if (style.parentNode === null) {
return false;
}

style.parentNode.removeChild(style);
}

/* istanbul ignore next */
const replaceText = (function replaceText() {
const textStore = [];

return function replace(index, replacement) {
textStore[index] = replacement;

return textStore.filter(Boolean).join('\n');
};
})();

function applyToSingletonTag(style, index, remove, obj) {
const css = remove
? ''
: obj.media
? `@media ${obj.media} {${obj.css}}`
: obj.css;

// For old IE
/* istanbul ignore if */
if (style.styleSheet) {
style.styleSheet.cssText = replaceText(index, css);
} else {
const cssNode = document.createTextNode(css);
const childNodes = style.childNodes;

if (childNodes[index]) {
style.removeChild(childNodes[index]);
}

if (childNodes.length) {
style.insertBefore(cssNode, childNodes[index]);
} else {
style.appendChild(cssNode);
}
}
}

function applyToTag(style, options, obj) {
let css = obj.css;
const media = obj.media;
const sourceMap = obj.sourceMap;

if (media) {
style.setAttribute('media', media);
} else {
style.removeAttribute('media');
}

if (sourceMap && btoa) {
css += `\n/*# sourceMappingURL=data:application/json;base64,${btoa(
unescape(encodeURIComponent(JSON.stringify(sourceMap)))
)} */`;
}

// For old IE
/* istanbul ignore if */
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
while (style.firstChild) {
style.removeChild(style.firstChild);
}

style.appendChild(document.createTextNode(css));
}
}

let singleton = null;
let singletonCounter = 0;

function addStyle(obj, options) {
let style;
let update;
let remove;

if (options.singleton) {
const styleIndex = singletonCounter++;

style = singleton || (singleton = insertStyleElement(options));

update = applyToSingletonTag.bind(null, style, styleIndex, false);
remove = applyToSingletonTag.bind(null, style, styleIndex, true);
} else {
style = insertStyleElement(options);

update = applyToTag.bind(null, style, options);
remove = () => {
removeStyleElement(style);
};
}

update(obj);

return function updateStyle(newObj) {
if (newObj) {
if (
newObj.css === obj.css &&
newObj.media === obj.media &&
newObj.sourceMap === obj.sourceMap
) {
return;
}

update((obj = newObj));
} else {
remove();
}
};
}

module.exports = (list, options) => {
options = options || {};

// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page
if (!options.singleton && typeof options.singleton !== 'boolean') {
options.singleton = isOldIE();
}

list = list || [];

let lastIdentifiers = modulesToDom(list, options);

return function update(newList) {
newList = newList || [];

if (Object.prototype.toString.call(newList) !== '[object Array]') {
return;
}

for (let i = 0; i < lastIdentifiers.length; i++) {
const identifier = lastIdentifiers[i];
const index = getIndexByIdentifier(identifier);

stylesInDom[index].references--;
}

const newLastIdentifiers = modulesToDom(newList, options);

for (let i = 0; i < lastIdentifiers.length; i++) {
const identifier = lastIdentifiers[i];
const index = getIndexByIdentifier(identifier);

if (stylesInDom[index].references === 0) {
stylesInDom[index].updater();
stylesInDom.splice(index, 1);
}
}

lastIdentifiers = newLastIdentifiers;
};
};
319 changes: 319 additions & 0 deletions test/__snapshots__/attributes-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"attributes" option should add attributes to tag when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">body {
color: red;
}
h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">body {
color: red;
}
</style><style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" href=\\"style.css\\" type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\"><link rel=\\"stylesheet\\" href=\\"style-other.css\\" type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\"></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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 when the "injectType" option is "linkTag": warnings 1`] = `Array []`;
exports[`"attributes" option should add attributes to tag when the "injectType" option is "singletonStyleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">body {
color: red;
}
h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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 when the "injectType" option is "singletonStyleTag": warnings 1`] = `Array []`;
exports[`"attributes" option should add attributes to tag when the "injectType" option is "styleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">body {
color: red;
}
</style><style type=\\"text/css\\" foo=\\"bar\\" data-id=\\"style-tag-id\\">h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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 when the "injectType" option is "styleTag": warnings 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazySingletonStyleTag" #2: DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazySingletonStyleTag" #2: errors 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 when "injectType" option is "lazySingletonStyleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazySingletonStyleTag": errors 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazySingletonStyleTag": warnings 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: errors 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag" #2: warnings 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag": errors 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "lazyStyleTag": warnings 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "linkTag" #2: DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" href=\\"style.css\\" nonce=\\"12345678\\"></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "linkTag" #2: errors 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "linkTag" #2: warnings 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "linkTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" href=\\"style.css\\" nonce=\\"12345678\\"></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style nonce=\\"12345678\\">body {
color: red;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "styleTag": errors 1`] = `Array []`;
exports[`"attributes" option should add nonce attribute when "injectType" option is "styleTag": warnings 1`] = `Array []`;
25 changes: 25 additions & 0 deletions test/__snapshots__/base-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"base" option should work: DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style>body {
color: red;
}
</style><style>h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
exports[`"base" option should work: errors 1`] = `Array []`;
exports[`"base" option should work: warnings 1`] = `Array []`;
799 changes: 799 additions & 0 deletions test/__snapshots__/esModule-option.test.js.snap

Large diffs are not rendered by default.

115 changes: 115 additions & 0 deletions test/__snapshots__/injectType-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"injectType" option should work when the "injectType" option is "lazySingletonStyleTag": DOM 1`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style>body {
color: red;
}
h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style>body {
color: red;
}
</style><style>h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<link rel=\\"stylesheet\\" href=\\"style.css\\"><link rel=\\"stylesheet\\" href=\\"style-other.css\\"></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style>body {
color: red;
}
h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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`] = `
"<!DOCTYPE html><html><head>
<title>style-loader test</title>
<style id=\\"existing-style\\">.existing { color: yellow }</style>
<style>body {
color: red;
}
</style><style>h1 {
color: blue;
}
</style></head>
<body>
<h1>Body</h1>
<div class=\\"target\\"></div>
<iframe class=\\"iframeTarget\\"></iframe>
</body></html>"
`;
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 []`;
817 changes: 817 additions & 0 deletions test/__snapshots__/insert-option.test.js.snap

Large diffs are not rendered by default.

807 changes: 807 additions & 0 deletions test/__snapshots__/loader.test.js.snap

Large diffs are not rendered by default.

79 changes: 79 additions & 0 deletions test/__snapshots__/validate-options.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`validate options should throw an error on the "attributes" option with "true" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options.attributes should be an object:
object {}
-> Adds custom attributes to tag (https://github.com/webpack-contrib/style-loader#attributes)."
`;

exports[`validate options should throw an error on the "esModule" option with "true" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options.esModule should be a boolean.
-> Use the ES modules syntax (https://github.com/webpack-contrib/css-loader#esmodule)."
`;

exports[`validate options should throw an error on the "injectType" option with "unknown" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options.injectType should be one of these:
\\"styleTag\\" | \\"singletonStyleTag\\" | \\"lazyStyleTag\\" | \\"lazySingletonStyleTag\\" | \\"linkTag\\"
-> Allows to setup how styles will be injected into DOM (https://github.com/webpack-contrib/style-loader#injecttype)."
`;

exports[`validate options should throw an error on the "insert" option with "true" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options.insert should be one of these:
string | function
-> Inserts \`<style>\`/\`<link>\` at the given position (https://github.com/webpack-contrib/style-loader#insert).
Details:
* options.insert should be a string.
* options.insert should be an instance of function."
`;
exports[`validate options should throw an error on the "unknown" option with "/test/" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "[]" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{"foo":"bar"}" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "{}" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "1" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "false" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "test" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
exports[`validate options should throw an error on the "unknown" option with "true" value 1`] = `
"Invalid options object. Style Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'unknown'. These properties are valid:
object { injectType?, attributes?, insert?, base?, esModule? }"
`;
72 changes: 72 additions & 0 deletions test/attributes-option.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
compile,
getCompiler,
getEntryByInjectType,
getErrors,
getWarnings,
runInJsDom,
} from './helpers/index';

describe('"attributes" option', () => {
const injectTypes = [
'styleTag',
'singletonStyleTag',
'lazyStyleTag',
'lazySingletonStyleTag',
'linkTag',
];

injectTypes.forEach((injectType) => {
it(`should add attributes to tag when the "injectType" option is "${injectType}"`, async () => {
expect.assertions(3);

const entry = getEntryByInjectType('simple.js', injectType);
const compiler = getCompiler(entry, {
injectType,
attributes: {
type: 'text/css',
foo: 'bar',
'data-id': 'style-tag-id',
},
});
const stats = await compile(compiler);

runInJsDom('main.bundle.js', compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot('DOM');
});

expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it(`should add nonce attribute when "injectType" option is "${injectType}"`, async () => {
expect.assertions(3);

const entry = getEntryByInjectType('nonce-require.js', injectType);
const compiler = getCompiler(entry, { injectType });
const stats = await compile(compiler);

runInJsDom('main.bundle.js', compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot('DOM');
});

expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it(`should add nonce attribute when "injectType" option is "${injectType}" #2`, async () => {
expect.assertions(3);

const entry = getEntryByInjectType('nonce-import.js', injectType);
const compiler = getCompiler(entry, { injectType });
const stats = await compile(compiler);

runInJsDom('main.bundle.js', compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot('DOM');
});

expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});
});
23 changes: 23 additions & 0 deletions test/base-option.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
compile,
getCompiler,
getErrors,
getWarnings,
runInJsDom,
} from './helpers/index';

describe('"base" option', () => {
it('should work', async () => {
expect.assertions(3);

const compiler = getCompiler('./simple.js', { base: 1000 });
const stats = await compile(compiler);

runInJsDom('main.bundle.js', compiler, stats, (dom) => {
expect(dom.serialize()).toMatchSnapshot('DOM');
});

expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});
Loading