web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

893 lines
19 KiB

  1. <div align="center">
  2. <a href="https://github.com/webpack/webpack">
  3. <img width="200" height="200"
  4. src="https://webpack.js.org/assets/icon-square-big.svg">
  5. </a>
  6. <h1>Style Loader</h1>
  7. </div>
  8. [![npm][npm]][npm-url]
  9. [![node][node]][node-url]
  10. [![deps][deps]][deps-url]
  11. [![tests][tests]][tests-url]
  12. [![coverage][cover]][cover-url]
  13. [![chat][chat]][chat-url]
  14. [![size][size]][size-url]
  15. # style-loader
  16. Inject CSS into the DOM.
  17. ## Getting Started
  18. To begin, you'll need to install `style-loader`:
  19. ```console
  20. npm install --save-dev style-loader
  21. ```
  22. It's recommended to combine `style-loader` with the [`css-loader`](https://github.com/webpack-contrib/css-loader)
  23. Then add the loader to your `webpack` config. For example:
  24. **style.css**
  25. ```css
  26. body {
  27. background: green;
  28. }
  29. ```
  30. **component.js**
  31. ```js
  32. import './style.css';
  33. ```
  34. **webpack.config.js**
  35. ```js
  36. module.exports = {
  37. module: {
  38. rules: [
  39. {
  40. test: /\.css$/i,
  41. use: ['style-loader', 'css-loader'],
  42. },
  43. ],
  44. },
  45. };
  46. ```
  47. ## Options
  48. | Name | Type | Default | Description |
  49. | :-----------------------------: | :------------------: | :---------: | :------------------------------------------------------- |
  50. | [**`injectType`**](#injecttype) | `{String}` | `styleTag` | Allows to setup how styles will be injected into the DOM |
  51. | [**`attributes`**](#attributes) | `{Object}` | `{}` | Adds custom attributes to tag |
  52. | [**`insert`**](#insert) | `{String\|Function}` | `head` | Inserts tag at the given position into the DOM |
  53. | [**`base`**](#base) | `{Number}` | `true` | Sets module ID base (DLLPlugin) |
  54. | [**`esModule`**](#esmodule) | `{Boolean}` | `false` | Use ES modules syntax |
  55. | [**`modules`**](#modules) | `{Object}` | `undefined` | Configuration CSS Modules |
  56. ### `injectType`
  57. Type: `String`
  58. Default: `styleTag`
  59. Allows to setup how styles will be injected into the DOM.
  60. Possible values:
  61. - `styleTag`
  62. - `singletonStyleTag`
  63. - `lazyStyleTag`
  64. - `lazySingletonStyleTag`
  65. - `linkTag`
  66. #### `styleTag`
  67. Automatically injects styles into the DOM using multiple `<style></style>`. It is **default** behaviour.
  68. **component.js**
  69. ```js
  70. import './styles.css';
  71. ```
  72. Example with Locals (CSS Modules):
  73. **component-with-css-modules.js**
  74. ```js
  75. import styles from './styles.css';
  76. const divElement = document.createElement('div');
  77. divElement.className = styles['my-class'];
  78. ```
  79. All locals (class names) stored in imported object.
  80. **webpack.config.js**
  81. ```js
  82. module.exports = {
  83. module: {
  84. rules: [
  85. {
  86. test: /\.css$/i,
  87. use: [
  88. // The `injectType` option can be avoided because it is default behaviour
  89. { loader: 'style-loader', options: { injectType: 'styleTag' } },
  90. 'css-loader',
  91. ],
  92. },
  93. ],
  94. },
  95. };
  96. ```
  97. The loader inject styles like:
  98. ```html
  99. <style>
  100. .foo {
  101. color: red;
  102. }
  103. </style>
  104. <style>
  105. .bar {
  106. color: blue;
  107. }
  108. </style>
  109. ```
  110. #### `singletonStyleTag`
  111. Automatically injects styles into the DOM using one `<style></style>`.
  112. > ⚠ Source maps do not work.
  113. **component.js**
  114. ```js
  115. import './styles.css';
  116. ```
  117. **component-with-css-modules.js**
  118. ```js
  119. import styles from './styles.css';
  120. const divElement = document.createElement('div');
  121. divElement.className = styles['my-class'];
  122. ```
  123. All locals (class names) stored in imported object.
  124. **webpack.config.js**
  125. ```js
  126. module.exports = {
  127. module: {
  128. rules: [
  129. {
  130. test: /\.css$/i,
  131. use: [
  132. {
  133. loader: 'style-loader',
  134. options: { injectType: 'singletonStyleTag' },
  135. },
  136. 'css-loader',
  137. ],
  138. },
  139. ],
  140. },
  141. };
  142. ```
  143. The loader inject styles like:
  144. ```html
  145. <style>
  146. .foo {
  147. color: red;
  148. }
  149. .bar {
  150. color: blue;
  151. }
  152. </style>
  153. ```
  154. #### `lazyStyleTag`
  155. Injects styles into the DOM using multiple `<style></style>` on demand.
  156. We recommend following `.lazy.css` naming convention for lazy styles and the `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`).
  157. When you `lazyStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
  158. > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
  159. **component.js**
  160. ```js
  161. import styles from './styles.lazy.css';
  162. styles.use();
  163. // For removing styles you can use
  164. // styles.unuse();
  165. ```
  166. **component-with-css-modules.js**
  167. ```js
  168. import styles from './styles.lazy.css';
  169. styles.use();
  170. const divElement = document.createElement('div');
  171. divElement.className = styles.locals['my-class'];
  172. ```
  173. All locals (class names) stored in `locals` property of imported object.
  174. **webpack.config.js**
  175. ```js
  176. module.exports = {
  177. module: {
  178. rules: [
  179. {
  180. test: /\.css$/i,
  181. exclude: /\.lazy\.css$/i,
  182. use: ['style-loader', 'css-loader'],
  183. },
  184. {
  185. test: /\.lazy\.css$/i,
  186. use: [
  187. { loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
  188. 'css-loader',
  189. ],
  190. },
  191. ],
  192. },
  193. };
  194. ```
  195. The loader inject styles like:
  196. ```html
  197. <style>
  198. .foo {
  199. color: red;
  200. }
  201. </style>
  202. <style>
  203. .bar {
  204. color: blue;
  205. }
  206. </style>
  207. ```
  208. #### `lazySingletonStyleTag`
  209. Injects styles into the DOM using one `<style></style>` on demand.
  210. We recommend following `.lazy.css` naming convention for lazy styles and the `.css` for basic `style-loader` usage (similar to other file types, i.e. `.lazy.less` and `.less`).
  211. When you `lazySingletonStyleTag` value the `style-loader` injects the styles lazily making them useable on-demand via `style.use()` / `style.unuse()`.
  212. > ⚠️ Source maps do not work.
  213. > ⚠️ Behavior is undefined when `unuse` is called more often than `use`. Don't do that.
  214. **component.js**
  215. ```js
  216. import styles from './styles.css';
  217. styles.use();
  218. // For removing styles you can use
  219. // styles.unuse();
  220. ```
  221. **component-with-css-modules.js**
  222. ```js
  223. import styles from './styles.lazy.css';
  224. styles.use();
  225. const divElement = document.createElement('div');
  226. divElement.className = styles.locals['my-class'];
  227. ```
  228. All locals (class names) stored in `locals` property of imported object.
  229. **webpack.config.js**
  230. ```js
  231. module.exports = {
  232. module: {
  233. rules: [
  234. {
  235. test: /\.css$/i,
  236. exclude: /\.lazy\.css$/i,
  237. use: ['style-loader', 'css-loader'],
  238. },
  239. {
  240. test: /\.lazy\.css$/i,
  241. use: [
  242. {
  243. loader: 'style-loader',
  244. options: { injectType: 'lazySingletonStyleTag' },
  245. },
  246. 'css-loader',
  247. ],
  248. },
  249. ],
  250. },
  251. };
  252. ```
  253. The loader generate this:
  254. ```html
  255. <style>
  256. .foo {
  257. color: red;
  258. }
  259. .bar {
  260. color: blue;
  261. }
  262. </style>
  263. ```
  264. #### `linkTag`
  265. Injects styles into the DOM using multiple `<link rel="stylesheet" href="path/to/file.css">` .
  266. > ℹ️ The loader will dynamically insert the `<link href="path/to/file.css" rel="stylesheet">` tag at runtime via JavaScript. You should use [MiniCssExtractPlugin](https://webpack.js.org/plugins/mini-css-extract-plugin/) if you want to include a static `<link href="path/to/file.css" rel="stylesheet">`.
  267. ```js
  268. import './styles.css';
  269. import './other-styles.css';
  270. ```
  271. **webpack.config.js**
  272. ```js
  273. module.exports = {
  274. module: {
  275. rules: [
  276. {
  277. test: /\.link\.css$/i,
  278. use: [
  279. { loader: 'style-loader', options: { injectType: 'linkTag' } },
  280. { loader: 'file-loader' },
  281. ],
  282. },
  283. ],
  284. },
  285. };
  286. ```
  287. The loader generate this:
  288. ```html
  289. <link rel="stylesheet" href="path/to/style.css" />
  290. <link rel="stylesheet" href="path/to/other-styles.css" />
  291. ```
  292. ### `attributes`
  293. Type: `Object`
  294. Default: `{}`
  295. If defined, the `style-loader` will attach given attributes with their values on `<style>` / `<link>` element.
  296. **component.js**
  297. ```js
  298. import style from './file.css';
  299. ```
  300. **webpack.config.js**
  301. ```js
  302. module.exports = {
  303. module: {
  304. rules: [
  305. {
  306. test: /\.css$/i,
  307. use: [
  308. { loader: 'style-loader', options: { attributes: { id: 'id' } } },
  309. { loader: 'css-loader' },
  310. ],
  311. },
  312. ],
  313. },
  314. };
  315. ```
  316. ```html
  317. <style id="id"></style>
  318. ```
  319. ### `insert`
  320. Type: `String|Function`
  321. Default: `head`
  322. By default, the `style-loader` appends `<style>`/`<link>` elements to the end of the style target, which is the `<head>` tag of the page unless specified by `insert`.
  323. This will cause CSS created by the loader to take priority over CSS already present in the target.
  324. You can use other values if the standard behavior is not suitable for you, but we do not recommend doing this.
  325. If you target an [iframe](https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement) make sure you have sufficient access rights, the styles will be injected into the content document head.
  326. #### `String`
  327. Allows to setup custom [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector) where styles inject into the DOM.
  328. **webpack.config.js**
  329. ```js
  330. module.exports = {
  331. module: {
  332. rules: [
  333. {
  334. test: /\.css$/i,
  335. use: [
  336. {
  337. loader: 'style-loader',
  338. options: {
  339. insert: 'body',
  340. },
  341. },
  342. 'css-loader',
  343. ],
  344. },
  345. ],
  346. },
  347. };
  348. ```
  349. A new `<style>`/`<link>` elements will be inserted into at bottom of `body` tag.
  350. #### `Function`
  351. Allows to override default behavior and insert styles at any position.
  352. > ⚠ Do not forget that this code will be used in the browser and not all browsers support latest ECMA features like `let`, `const`, `arrow function expression` and etc, we recommend use only ECMA 5 features, but it is depends what browsers you want to support
  353. > ⚠ Do not forget that some DOM methods may not be available in older browsers, we recommended use only [DOM core level 2 properties](https://caniuse.com/#search=DOM%20Core), but it is depends what browsers you want to support
  354. **webpack.config.js**
  355. ```js
  356. module.exports = {
  357. module: {
  358. rules: [
  359. {
  360. test: /\.css$/i,
  361. use: [
  362. {
  363. loader: 'style-loader',
  364. options: {
  365. insert: function insertAtTop(element) {
  366. var parent = document.querySelector('head');
  367. // eslint-disable-next-line no-underscore-dangle
  368. var lastInsertedElement =
  369. window._lastElementInsertedByStyleLoader;
  370. if (!lastInsertedElement) {
  371. parent.insertBefore(element, parent.firstChild);
  372. } else if (lastInsertedElement.nextSibling) {
  373. parent.insertBefore(element, lastInsertedElement.nextSibling);
  374. } else {
  375. parent.appendChild(element);
  376. }
  377. // eslint-disable-next-line no-underscore-dangle
  378. window._lastElementInsertedByStyleLoader = element;
  379. },
  380. },
  381. },
  382. 'css-loader',
  383. ],
  384. },
  385. ],
  386. },
  387. };
  388. ```
  389. Insert styles at top of `head` tag.
  390. ### `base`
  391. 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.:
  392. **webpack.dll1.config.js**
  393. ```js
  394. module.exports = {
  395. module: {
  396. rules: [
  397. {
  398. test: /\.css$/i,
  399. use: ['style-loader', 'css-loader'],
  400. },
  401. ],
  402. },
  403. };
  404. ```
  405. **webpack.dll2.config.js**
  406. ```js
  407. module.exports = {
  408. module: {
  409. rules: [
  410. {
  411. test: /\.css$/i,
  412. use: [
  413. { loader: 'style-loader', options: { base: 1000 } },
  414. 'css-loader',
  415. ],
  416. },
  417. ],
  418. },
  419. };
  420. ```
  421. **webpack.app.config.js**
  422. ```js
  423. module.exports = {
  424. module: {
  425. rules: [
  426. {
  427. test: /\.css$/i,
  428. use: [
  429. { loader: 'style-loader', options: { base: 2000 } },
  430. 'css-loader',
  431. ],
  432. },
  433. ],
  434. },
  435. };
  436. ```
  437. ### `esModule`
  438. Type: `Boolean`
  439. Default: `false`
  440. By default, `style-loader` generates JS modules that use the CommonJS modules syntax.
  441. There are some cases in which using ES modules is beneficial, like in the case of [module concatenation](https://webpack.js.org/plugins/module-concatenation-plugin/) and [tree shaking](https://webpack.js.org/guides/tree-shaking/).
  442. You can enable a ES module syntax using:
  443. **webpack.config.js**
  444. ```js
  445. module.exports = {
  446. module: {
  447. rules: [
  448. {
  449. test: /\.css$/i,
  450. loader: 'style-loader',
  451. options: {
  452. esModule: true,
  453. },
  454. },
  455. ],
  456. },
  457. };
  458. ```
  459. ### `modules`
  460. Type: `Object`
  461. Default: `undefined`
  462. Configuration CSS Modules.
  463. #### `namedExport`
  464. Type: `Boolean`
  465. Default: `false`
  466. Enables/disables ES modules named export for locals.
  467. > ⚠ Names of locals are converted to `camelCase`.
  468. > ⚠ It is not allowed to use JavaScript reserved words in css class names.
  469. > ⚠ Options `esModule` and `modules.namedExport` in `css-loader` and `style-loader` should be enabled.
  470. **styles.css**
  471. ```css
  472. .foo-baz {
  473. color: red;
  474. }
  475. .bar {
  476. color: blue;
  477. }
  478. ```
  479. **index.js**
  480. ```js
  481. import { fooBaz, bar } from './styles.css';
  482. console.log(fooBaz, bar);
  483. ```
  484. You can enable a ES module named export using:
  485. **webpack.config.js**
  486. ```js
  487. module.exports = {
  488. module: {
  489. rules: [
  490. {
  491. test: /\.css$/,
  492. use: [
  493. {
  494. loader: 'style-loader',
  495. options: {
  496. esModule: true,
  497. modules: {
  498. namedExport: true,
  499. },
  500. },
  501. },
  502. {
  503. loader: 'css-loader',
  504. options: {
  505. esModule: true,
  506. modules: {
  507. namedExport: true,
  508. },
  509. },
  510. },
  511. ],
  512. },
  513. ],
  514. },
  515. };
  516. ```
  517. ## Examples
  518. ### Source maps
  519. The loader automatically inject source maps when previous loader emit them.
  520. Therefore, to generate source maps, set the `sourceMap` option to `true` for the previous loader.
  521. **webpack.config.js**
  522. ```js
  523. module.exports = {
  524. module: {
  525. rules: [
  526. {
  527. test: /\.css$/i,
  528. use: [
  529. 'style-loader',
  530. { loader: 'css-loader', options: { sourceMap: true } },
  531. ],
  532. },
  533. ],
  534. },
  535. };
  536. ```
  537. ### Nonce
  538. There are two ways to work with `nonce`:
  539. - using the `attributes` option
  540. - using the `__webpack_nonce__` variable
  541. > ⚠ the `attributes` option takes precedence over the `__webpack_nonce__` variable
  542. #### `attributes`
  543. **component.js**
  544. ```js
  545. import './style.css';
  546. ```
  547. **webpack.config.js**
  548. ```js
  549. module.exports = {
  550. module: {
  551. rules: [
  552. {
  553. test: /\.css$/i,
  554. use: [
  555. {
  556. loader: 'style-loader',
  557. options: {
  558. attributes: {
  559. nonce: '12345678',
  560. },
  561. },
  562. },
  563. 'css-loader',
  564. ],
  565. },
  566. ],
  567. },
  568. };
  569. ```
  570. The loader generate:
  571. ```html
  572. <style nonce="12345678">
  573. .foo {
  574. color: red;
  575. }
  576. </style>
  577. ```
  578. #### `__webpack_nonce__`
  579. **create-nonce.js**
  580. ```js
  581. __webpack_nonce__ = '12345678';
  582. ```
  583. **component.js**
  584. ```js
  585. import './create-nonce.js';
  586. import './style.css';
  587. ```
  588. Alternative example for `require`:
  589. **component.js**
  590. ```js
  591. __webpack_nonce__ = '12345678';
  592. require('./style.css');
  593. ```
  594. **webpack.config.js**
  595. ```js
  596. module.exports = {
  597. module: {
  598. rules: [
  599. {
  600. test: /\.css$/i,
  601. use: ['style-loader', 'css-loader'],
  602. },
  603. ],
  604. },
  605. };
  606. ```
  607. The loader generate:
  608. ```html
  609. <style nonce="12345678">
  610. .foo {
  611. color: red;
  612. }
  613. </style>
  614. ```
  615. #### Insert styles at top
  616. Inserts styles at top of `head` tag.
  617. **webpack.config.js**
  618. ```js
  619. module.exports = {
  620. module: {
  621. rules: [
  622. {
  623. test: /\.css$/i,
  624. use: [
  625. {
  626. loader: 'style-loader',
  627. options: {
  628. insert: function insertAtTop(element) {
  629. var parent = document.querySelector('head');
  630. var lastInsertedElement =
  631. window._lastElementInsertedByStyleLoader;
  632. if (!lastInsertedElement) {
  633. parent.insertBefore(element, parent.firstChild);
  634. } else if (lastInsertedElement.nextSibling) {
  635. parent.insertBefore(element, lastInsertedElement.nextSibling);
  636. } else {
  637. parent.appendChild(element);
  638. }
  639. window._lastElementInsertedByStyleLoader = element;
  640. },
  641. },
  642. },
  643. 'css-loader',
  644. ],
  645. },
  646. ],
  647. },
  648. };
  649. ```
  650. #### Insert styles before target element
  651. Inserts styles before `#id` element.
  652. **webpack.config.js**
  653. ```js
  654. module.exports = {
  655. module: {
  656. rules: [
  657. {
  658. test: /\.css$/i,
  659. use: [
  660. {
  661. loader: 'style-loader',
  662. options: {
  663. insert: function insertBeforeAt(element) {
  664. const parent = document.querySelector('head');
  665. const target = document.querySelector('#id');
  666. const lastInsertedElement =
  667. window._lastElementInsertedByStyleLoader;
  668. if (!lastInsertedElement) {
  669. parent.insertBefore(element, target);
  670. } else if (lastInsertedElement.nextSibling) {
  671. parent.insertBefore(element, lastInsertedElement.nextSibling);
  672. } else {
  673. parent.appendChild(element);
  674. }
  675. window._lastElementInsertedByStyleLoader = element;
  676. },
  677. },
  678. },
  679. 'css-loader',
  680. ],
  681. },
  682. ],
  683. },
  684. };
  685. ```
  686. ## Contributing
  687. Please take a moment to read our contributing guidelines if you haven't yet done so.
  688. [CONTRIBUTING](./.github/CONTRIBUTING.md)
  689. ## License
  690. [MIT](./LICENSE)
  691. [npm]: https://img.shields.io/npm/v/style-loader.svg
  692. [npm-url]: https://npmjs.com/package/style-loader
  693. [node]: https://img.shields.io/node/v/style-loader.svg
  694. [node-url]: https://nodejs.org
  695. [deps]: https://david-dm.org/webpack-contrib/style-loader.svg
  696. [deps-url]: https://david-dm.org/webpack-contrib/style-loader
  697. [tests]: https://github.com/webpack-contrib/style-loader/workflows/style-loader/badge.svg
  698. [tests-url]: https://github.com/webpack-contrib/style-loader/actions
  699. [cover]: https://codecov.io/gh/webpack-contrib/style-loader/branch/master/graph/badge.svg
  700. [cover-url]: https://codecov.io/gh/webpack-contrib/style-loader
  701. [chat]: https://badges.gitter.im/webpack/webpack.svg
  702. [chat-url]: https://gitter.im/webpack/webpack
  703. [size]: https://packagephobia.now.sh/badge?p=style-loader
  704. [size-url]: https://packagephobia.now.sh/result?p=style-loader