first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
"use strict";var _md=_interopRequireDefault(require("md5")),_compiler=require("@hap-toolkit/compiler"),_sharedUtils=require("@hap-toolkit/shared-utils");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const fileCache=new Map;module.exports=function(e){this.cacheable&&this.cacheable();const t=this.resourcePath;if(fileCache.has((0,_md.default)(e)))return e;fileCache.set((0,_md.default)(e),e);const l=require("vue-template-compiler").parseComponent(e,{pad:!0});if(l.template){const{log:e}=(0,_compiler.parseTemplate)(l.template.content,{filePath:t});e&&e.length&&(0,_sharedUtils.logWarn)(this,e)}return l.styles.length>0&&l.styles.forEach(e=>{if(e.lang||"css"!==e.lang)return;const{log:l}=(0,_compiler.parseStyle)({filePath:t,code:e.content});l&&l.length&&(0,_sharedUtils.logWarn)(this,l,!1)}),e};
//# sourceMappingURL=validator-loader.js.map
+2
View File
@@ -0,0 +1,2 @@
"use strict";var _compiler=require("@hap-toolkit/compiler");class Css2jsonPlugin{constructor(s){this.options=s}apply(s){s.hooks.emit.tapAsync("Css2jsonPlugin",(s,t)=>{for(const t in s.assets)if(t.match(/css\.json$/)){const e=s.assets[t]._source.children.filter(s=>s._value),o=e.length;e.map((s,e)=>{this.css2Json({code:s._value,filePath:t},t=>{let c="";0===e?(c='{"list":['+t,c+=e===o-1?"]}":","):(c=t,c+=e<o-1?",":"]}"),s._value=c})})}t()}),s.hooks.afterEmit.tapAsync("Css2jsonPlugin",(s,t)=>{for(const t in s.assets)t.match(/css\.json$/)&&(s.assets[t]._source.children=[]);t()})}css2Json(s,t){const e=String(s.code).match(/\[(.*)\]/);let o={};const{parsed:c}=(0,_compiler.parseStyle)(s);let n=c;if(e&&e[1]){o[e[1]]=n}else o=n;t&&t(o)}}module.exports=Css2jsonPlugin;
//# sourceMappingURL=css2json-plugin.js.map
+2
View File
@@ -0,0 +1,2 @@
"use strict";var _path=_interopRequireDefault(require("path")),_webpackSources=require("webpack-sources");function _interopRequireDefault(n){return n&&n.__esModule?n:{default:n}}const extList=[".mix",".ux",".vue"];class InstVuePlugin{constructor(n){this.options=n}apply(n){const e=this;n.hooks.compilation.tap("InstVuePlugin",(function(n){n.hooks.optimizeChunkAssets.tapAsync("InstVuePlugin",(function(t,o){t.forEach((function(t){_path.default.extname(Array.from(t.entryModule.buildInfo.fileDependencies)[0])===extList[2]&&t.files.forEach((function(t){const o=e.instVue(t,n);o&&(n.assets[t]=o)}))})),o()}))}))}instVue(n,e){if(/\.js$/.test(n))return n.match(/\bapp\.js$/)?new _webpackSources.ConcatSource("(function(){\n var handler = function() {\n return ",e.assets[n],`\n };\n if (typeof window === "undefined") {\n let options = handler();\n options.default['manifest'] = ${JSON.stringify(global.framework.manifest)}\n $app_define$(options.default)\n $app_bootstrap$()\n }\n })();`):new _webpackSources.ConcatSource("(function(){\n var handler = function() {\n return ",e.assets[n],"\n };\n if (typeof window === \"undefined\") {\n let options = handler();\n options = options.default ? options.default: options\n options['type'] = 'page'\n new Vue({render: function(h) {return h(options)}}).$mount('#app')\n }\n })();")}}module.exports=InstVuePlugin;
//# sourceMappingURL=instvue-plugin.js.map
+2
View File
@@ -0,0 +1,2 @@
"use strict";const path=require("path");module.exports={app:{demo:path.resolve(__dirname,"../templates/app/demo")}};
//# sourceMappingURL=template.js.map
+2
View File
@@ -0,0 +1,2 @@
"use strict";const VueLoaderPlugin=require("vue-loader/lib/plugin"),MiniCssExtractPlugin=require("mini-css-extract-plugin"),Css2jsonPlugin=require("./plugin/css2json-plugin"),InstVuePlugin=require("./plugin/instvue-plugin");module.exports.postHook=function(e,{cwd:s},r){let o;r.hapConfig?(o=r.hapConfig,o.webpack&&(o=o.webpack)):o={module:{rules:[{test:/\.css$/,use:[MiniCssExtractPlugin.loader,"css-loader"]},{test:/\.vue$/,use:{loader:require.resolve("vue-loader"),options:{hotReload:!1,compilerOptions:{preserveWhitespace:!1}}}},{test:/\.(png|jpe?g|gif|svg|bmp|webp|mp4|wmv|avi|mpg|rmvb|mov|flv|otf|ttf|ttc|woff|eot)$/i,use:{loader:require.resolve("url-loader")}}]},plugins:[new VueLoaderPlugin,new MiniCssExtractPlugin({filename:"[name].css.json"})]},(o&&o.module&&o.module.rules||[]).forEach(s=>{s.test.exec(".vue")&&(r.loaderWrapper(s),r.enableE2e&&s.use.push({loader:require.resolve("@hap-toolkit/packager/lib/loader/inject-suite-loader.js"),options:{hookName:"beforeCreate"}}),s.use.push({loader:require.resolve("./loader/validator-loader")})),s.test.exec(".ts")&&r.loaderWrapper(s),e.module.rules.push(s)}),e.plugins.push(...o&&o.plugins||[]),e.plugins.push(new Css2jsonPlugin,new InstVuePlugin),Object.keys(e.resolve).forEach(s=>{const r=e.resolve[s];r instanceof Array?r.push(...o.resolve&&o.resolve[s]||[]):"object"==typeof r&&null!==r&&Object.assign(r,o.resolve&&o.resolve[s]||{})}),Object.keys(o&&o.resolve||{}).forEach(s=>{s in e.resolve||(e.resolve[s]=o.resolve[s])})};
//# sourceMappingURL=webpack.post.js.map
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
else
exec node "$basedir/../mime/cli.js" "$@"
fi
+17
View File
@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
} else {
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../mime/cli.js" $args
} else {
& "node$exe" "$basedir/../mime/cli.js" $args
}
$ret=$LASTEXITCODE
}
exit $ret
+274
View File
@@ -0,0 +1,274 @@
# Change Log
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.
<a name="2.1.1"></a>
## [2.1.1](https://github.com/webpack-contrib/css-loader/compare/v2.1.0...v2.1.1) (2019-03-07)
### Bug Fixes
* do not break selector with escaping ([#896](https://github.com/webpack-contrib/css-loader/issues/896)) ([0ba8c66](https://github.com/webpack-contrib/css-loader/commit/0ba8c66))
* source map generation when `sourceRoot` is present ([#901](https://github.com/webpack-contrib/css-loader/issues/901)) ([e9ce745](https://github.com/webpack-contrib/css-loader/commit/e9ce745))
* sourcemap generating when previous loader pass sourcemap as string ([#905](https://github.com/webpack-contrib/css-loader/issues/905)) ([3797e4d](https://github.com/webpack-contrib/css-loader/commit/3797e4d))
<a name="2.1.0"></a>
# [2.1.0](https://github.com/webpack-contrib/css-loader/compare/v2.0.2...v2.1.0) (2018-12-25)
### Features
* support `image-set` without `url` ([#879](https://github.com/webpack-contrib/css-loader/issues/879)) ([21884e2](https://github.com/webpack-contrib/css-loader/commit/21884e2))
<a name="2.0.2"></a>
## [2.0.2](https://github.com/webpack-contrib/css-loader/compare/v2.0.1...v2.0.2) (2018-12-21)
### Bug Fixes
* inappropriate modification of animation keywords ([#876](https://github.com/webpack-contrib/css-loader/issues/876)) ([dfb2f8e](https://github.com/webpack-contrib/css-loader/commit/dfb2f8e))
<a name="2.0.1"></a>
# [2.0.1](https://github.com/webpack-contrib/css-loader/compare/v2.0.0...v2.0.1) (2018-12-14)
### Bug Fixes
* safe checking if params are present for at rule ([#871](https://github.com/webpack-contrib/css-loader/issues/871)) ([a88fed1](https://github.com/webpack-contrib/css-loader/commit/a88fed1))
* `getLocalIdent` now accepts `false` value ([#865](https://github.com/webpack-contrib/css-loader/issues/865)) ([1825e8a](https://github.com/webpack-contrib/css-loader/commit/1825e8a))
<a name="2.0.0"></a>
# [2.0.0](https://github.com/webpack-contrib/css-loader/compare/v1.0.1...v2.0.0) (2018-12-07)
### Bug Fixes
* broken unucode characters ([#850](https://github.com/webpack-contrib/css-loader/issues/850)) ([f599c70](https://github.com/webpack-contrib/css-loader/commit/f599c70))
* correctly processing `urls()` with `?#hash` ([#803](https://github.com/webpack-contrib/css-loader/issues/803)) ([417d105](https://github.com/webpack-contrib/css-loader/commit/417d105))
* don't break loader on invalid or not exists url or import token ([#827](https://github.com/webpack-contrib/css-loader/issues/827)) ([9e52d26](https://github.com/webpack-contrib/css-loader/commit/9e52d26))
* don't duplicate import with same media in different case ([#819](https://github.com/webpack-contrib/css-loader/issues/819)) ([9f66e33](https://github.com/webpack-contrib/css-loader/commit/9f66e33))
* emit warnings on broken `import` at-rules ([#806](https://github.com/webpack-contrib/css-loader/issues/806)) ([4bdf08b](https://github.com/webpack-contrib/css-loader/commit/4bdf08b))
* handle uppercase `URL` in `import` at-rules ([#818](https://github.com/webpack-contrib/css-loader/issues/818)) ([3ebdcd5](https://github.com/webpack-contrib/css-loader/commit/3ebdcd5))
* inconsistent generate class names for css modules on difference os ([#812](https://github.com/webpack-contrib/css-loader/issues/812)) ([0bdf9b7](https://github.com/webpack-contrib/css-loader/commit/0bdf9b7))
* reduce number of `require` for `urls()` ([#854](https://github.com/webpack-contrib/css-loader/issues/854)) ([3338656](https://github.com/webpack-contrib/css-loader/commit/3338656))
* support deduplication of string module ids (optimization.namedModules) ([#789](https://github.com/webpack-contrib/css-loader/issues/789)) ([e3bb83a](https://github.com/webpack-contrib/css-loader/commit/e3bb83a))
* support module resolution in `composes` ([#845](https://github.com/webpack-contrib/css-loader/issues/845)) ([453248f](https://github.com/webpack-contrib/css-loader/commit/453248f))
* same `urls()` resolving logic for `modules` (`local` and `global`) and without modules ([#843](https://github.com/webpack-contrib/css-loader/issues/843)) ([fdcf687](https://github.com/webpack-contrib/css-loader/commit/fdcf687))
### Features
* allow to disable css modules and **disable their by default** ([#842](https://github.com/webpack-contrib/css-loader/issues/842)) ([889dc7f](https://github.com/webpack-contrib/css-loader/commit/889dc7f))
* disable `import` option doesn't affect on `composes` ([#822](https://github.com/webpack-contrib/css-loader/issues/822)) ([f9aa73c](https://github.com/webpack-contrib/css-loader/commit/f9aa73c))
* allow to filter `urls` ([#856](https://github.com/webpack-contrib/css-loader/issues/856)) ([5e702e7](https://github.com/webpack-contrib/css-loader/commit/5e702e7))
* allow to filter `import` at-rules ([#857](https://github.com/webpack-contrib/css-loader/issues/857)) ([5e6034c](https://github.com/webpack-contrib/css-loader/commit/5e6034c))
* emit warning on invalid `urls()` ([#832](https://github.com/webpack-contrib/css-loader/issues/832)) ([da95db8](https://github.com/webpack-contrib/css-loader/commit/da95db8))
* added `exportOnlyLocals` option ([#824](https://github.com/webpack-contrib/css-loader/issues/824)) ([e9327c0](https://github.com/webpack-contrib/css-loader/commit/e9327c0))
* reuse `postcss` ast from other loaders (i.e `postcss-loader`) ([#840](https://github.com/webpack-contrib/css-loader/issues/840)) ([1dad1fb](https://github.com/webpack-contrib/css-loader/commit/1dad1fb))
* schema options ([b97d997](https://github.com/webpack-contrib/css-loader/commit/b97d997))
### BREAKING CHANGES
* resolving logic for `url()` and `import` at-rules works the same everywhere, it does not matter whether css modules are enabled (with `global` and `local` module) or not. Examples - `url('image.png')` as `require('./image.png')`, `url('./image.png')` as `require('./image.png')`, `url('~module/image.png')` as `require('module/image.png')`.
* by default css modules are disabled (now `modules: false` disable all css modules features), you can return old behaviour change this on `modules: 'global'`
* `css-loader/locals` was dropped in favor `exportOnlyLocals` option
* `import` option only affect on `import` at-rules and doesn't affect on `composes` declarations
* invalid `@import` at rules now emit warnings
* use `postcss@7`
<a name="1.0.1"></a>
## [1.0.1](https://github.com/webpack-contrib/css-loader/compare/v1.0.0...v1.0.1) (2018-10-29)
### Bug Fixes
* **loader:** trim unquoted import urls ([#783](https://github.com/webpack-contrib/css-loader/issues/783)) ([21fcddf](https://github.com/webpack-contrib/css-loader/commit/21fcddf))
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/css-loader/compare/v0.28.11...v1.0.0) (2018-07-06)
### BREAKING CHANGES
* remove `minimize` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`cssnano`](https://github.com/cssnano/cssnano) or use [`optimize-cssnano-plugin`](https://github.com/intervolga/optimize-cssnano-plugin) plugin
* remove `module` option, use `modules` option instead
* remove `camelcase` option, use `camelCase` option instead
* remove `root` option, use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* remove `alias` option, use [`resolve.alias`](https://webpack.js.org/configuration/resolve/) feature or use [`postcss-loader`](https://github.com/postcss/postcss-loader) with [`postcss-url`](https://github.com/postcss/postcss-url) plugin
* update `postcss` to `6` version
* minimum require `nodejs` version is `6.9`
* minimum require `webpack` version is `4`
<a name="0.28.11"></a>
## [0.28.11](https://github.com/webpack-contrib/css-loader/compare/v0.28.10...v0.28.11) (2018-03-16)
### Bug Fixes
* **lib/processCss:** don't check `mode` for `url` handling (`options.modules`) ([#698](https://github.com/webpack-contrib/css-loader/issues/698)) ([c788450](https://github.com/webpack-contrib/css-loader/commit/c788450))
<a name="0.28.10"></a>
## [0.28.10](https://github.com/webpack-contrib/css-loader/compare/v0.28.9...v0.28.10) (2018-02-22)
### Bug Fixes
* **getLocalIdent:** add `rootContext` support (`webpack >= v4.0.0`) ([#681](https://github.com/webpack-contrib/css-loader/issues/681)) ([9f876d2](https://github.com/webpack-contrib/css-loader/commit/9f876d2))
<a name="0.28.9"></a>
## [0.28.9](https://github.com/webpack-contrib/css-loader/compare/v0.28.8...v0.28.9) (2018-01-17)
### Bug Fixes
* ignore invalid URLs (`url()`) ([#663](https://github.com/webpack-contrib/css-loader/issues/663)) ([d1d8221](https://github.com/webpack-contrib/css-loader/commit/d1d8221))
<a name="0.28.8"></a>
## [0.28.8](https://github.com/webpack-contrib/css-loader/compare/v0.28.7...v0.28.8) (2018-01-05)
### Bug Fixes
* **loader:** correctly check if source map is `undefined` ([#641](https://github.com/webpack-contrib/css-loader/issues/641)) ([0dccfa9](https://github.com/webpack-contrib/css-loader/commit/0dccfa9))
* proper URL escaping and wrapping (`url()`) ([#627](https://github.com/webpack-contrib/css-loader/issues/627)) ([8897d44](https://github.com/webpack-contrib/css-loader/commit/8897d44))
<a name="0.28.7"></a>
## [0.28.7](https://github.com/webpack/css-loader/compare/v0.28.6...v0.28.7) (2017-08-30)
### Bug Fixes
* pass resolver to `localsLoader` (`options.alias`) ([#601](https://github.com/webpack/css-loader/issues/601)) ([8f1b57c](https://github.com/webpack/css-loader/commit/8f1b57c))
<a name="0.28.6"></a>
## [0.28.6](https://github.com/webpack/css-loader/compare/v0.28.5...v0.28.6) (2017-08-30)
### Bug Fixes
* add support for aliases starting with `/` (`options.alias`) ([#597](https://github.com/webpack/css-loader/issues/597)) ([63567f2](https://github.com/webpack/css-loader/commit/63567f2))
<a name="0.28.5"></a>
## [0.28.5](https://github.com/webpack/css-loader/compare/v0.28.4...v0.28.5) (2017-08-17)
### Bug Fixes
* match mutliple dashes (`options.camelCase`) ([#556](https://github.com/webpack/css-loader/issues/556)) ([1fee601](https://github.com/webpack/css-loader/commit/1fee601))
* stricter `[@import](https://github.com/import)` tolerance ([#593](https://github.com/webpack/css-loader/issues/593)) ([2e4ec09](https://github.com/webpack/css-loader/commit/2e4ec09))
<a name="0.28.4"></a>
## [0.28.4](https://github.com/webpack/css-loader/compare/v0.28.3...v0.28.4) (2017-05-30)
### Bug Fixes
* preserve leading underscore in class names ([#543](https://github.com/webpack/css-loader/issues/543)) ([f6673c8](https://github.com/webpack/css-loader/commit/f6673c8))
<a name="0.28.3"></a>
## [0.28.3](https://github.com/webpack/css-loader/compare/v0.28.2...v0.28.3) (2017-05-25)
### Bug Fixes
* correct plugin order for CSS Modules ([#534](https://github.com/webpack/css-loader/issues/534)) ([b90f492](https://github.com/webpack/css-loader/commit/b90f492))
<a name="0.28.2"></a>
## [0.28.2](https://github.com/webpack/css-loader/compare/v0.28.1...v0.28.2) (2017-05-22)
### Bug Fixes
* source maps path on `windows` ([#532](https://github.com/webpack/css-loader/issues/532)) ([c3d0d91](https://github.com/webpack/css-loader/commit/c3d0d91))
<a name="0.28.1"></a>
## [0.28.1](https://github.com/webpack/css-loader/compare/v0.28.0...v0.28.1) (2017-05-02)
### Bug Fixes
* allow to specify a full hostname as a root URL ([#521](https://github.com/webpack/css-loader/issues/521)) ([06d27a1](https://github.com/webpack/css-loader/commit/06d27a1))
* case insensitivity of [@import](https://github.com/import) ([#514](https://github.com/webpack/css-loader/issues/514)) ([de4356b](https://github.com/webpack/css-loader/commit/de4356b))
* don't handle empty [@import](https://github.com/import) and url() ([#513](https://github.com/webpack/css-loader/issues/513)) ([868fc94](https://github.com/webpack/css-loader/commit/868fc94))
* imported variables are replaced in exports if followed by a comma ([#504](https://github.com/webpack/css-loader/issues/504)) ([956bad7](https://github.com/webpack/css-loader/commit/956bad7))
* loader now correctly handles `url` with space(s) ([#495](https://github.com/webpack/css-loader/issues/495)) ([534ea55](https://github.com/webpack/css-loader/commit/534ea55))
* url with a trailing space is now handled correctly ([#494](https://github.com/webpack/css-loader/issues/494)) ([e1ec4f2](https://github.com/webpack/css-loader/commit/e1ec4f2))
* use `btoa` instead `Buffer` ([#501](https://github.com/webpack/css-loader/issues/501)) ([fbb0714](https://github.com/webpack/css-loader/commit/fbb0714))
### Performance Improvements
* generate source maps only when explicitly set ([#478](https://github.com/webpack/css-loader/issues/478)) ([b8f5c8f](https://github.com/webpack/css-loader/commit/b8f5c8f))
<a name="0.28.0"></a>
# [0.28.0](https://github.com/webpack/css-loader/compare/v0.27.3...v0.28.0) (2017-03-30)
### Features
* add alias feature to rewrite URLs ([#274](https://github.com/webpack/css-loader/issues/274)) ([c8db489](https://github.com/webpack/css-loader/commit/c8db489))
<a name="0.27.3"></a>
## [0.27.3](https://github.com/webpack/css-loader/compare/v0.27.2...v0.27.3) (2017-03-13)
<a name="0.27.2"></a>
# [0.27.2](https://github.com/webpack/css-loader/compare/v0.27.1...v0.27.2) (2017-03-12)
<a name="0.27.1"></a>
# [0.27.1](https://github.com/webpack/css-loader/compare/v0.27.0...v0.27.1) (2017-03-10)
<a name="0.27.0"></a>
# [0.27.0](https://github.com/webpack/css-loader/compare/v0.26.2...v0.27.0) (2017-03-10)
### Bug Fixes
* **sourcemaps:** use abs paths & remove sourceRoot ([c769ac3](https://github.com/webpack/css-loader/commit/c769ac3))
* `minimizeOptions` should be `query.minimize`! ([16c0858](https://github.com/webpack/css-loader/commit/16c0858))
* do not export duplicate keys ([#420](https://github.com/webpack/css-loader/issues/420)) ([a2b85d7](https://github.com/webpack/css-loader/commit/a2b85d7))
### Features
* allow removal of original class name ([#445](https://github.com/webpack/css-loader/issues/445)) ([3f78361](https://github.com/webpack/css-loader/commit/3f78361))
* Include the sourceMappingURL & sourceURL when toString() ([6da7e90](https://github.com/webpack/css-loader/commit/6da7e90))
+20
View File
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+744
View File
@@ -0,0 +1,744 @@
<div align="center">
<img width="180" height="180" vspace="20"
src="https://cdn.worldvectorlogo.com/logos/css-3.svg">
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
</div>
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
[![size][size]][size-url]
# css-loader
The `css-loader` interprets `@import` and `url()` like `import/require()` and will resolve them.
## Getting Started
To begin, you'll need to install `css-loader`:
```console
npm install --save-dev css-loader
```
Then add the plugin to your `webpack` config. For example:
**file.js**
```js
import css from 'file.css';
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
};
```
Good loaders for requiring your assets are the [file-loader](https://github.com/webpack/file-loader) and the [url-loader](https://github.com/webpack/url-loader) which you should specify in your config (see [below](https://github.com/webpack-contrib/css-loader#assets)).
And run `webpack` via your preferred method.
### `toString`
You can also use the css-loader results directly as a string, such as in Angular's component style.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['to-string-loader', 'css-loader'],
},
],
},
};
```
or
```js
const css = require('./test.css').toString();
console.log(css); // {String}
```
If there are SourceMaps, they will also be included in the result string.
If, for one reason or another, you need to extract CSS as a
plain string resource (i.e. not wrapped in a JS module) you
might want to check out the [extract-loader](https://github.com/peerigon/extract-loader).
It's useful when you, for instance, need to post process the CSS as a string.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'handlebars-loader', // handlebars loader expects raw resource string
'extract-loader',
'css-loader',
],
},
],
},
};
```
## Options
| Name | Type | Default | Description |
| :-----------------------------------------: | :-------------------: | :-------------: | :----------------------------------------------------------------------- |
| **[`url`](#url)** | `{Boolean\|Function}` | `true` | Enable/Disable `url()` handling |
| **[`import`](#import)** | `{Boolean\/Function}` | `true` | Enable/Disable @import handling |
| **[`modules`](#modules)** | `{Boolean\|String}` | `false` | Enable/Disable CSS Modules and setup mode |
| **[`localIdentName`](#localidentname)** | `{String}` | `[hash:base64]` | Configure the generated ident |
| **[`context`](#context)** | `{String}` | `undefined` | Allow to redefine basic loader context for local ident name |
| **[`hashPrefix`](#hashprefix)** | `{String}` | `undefined` | Allow to add custom hash to generate more unique classes |
| **[`getLocalIdent`](#getlocalident)** | `{Function}` | `undefined` | Configure the function to generate classname based on a different schema |
| **[`sourceMap`](#sourcemap)** | `{Boolean}` | `false` | Enable/Disable Sourcemaps |
| **[`camelCase`](#camelcase)** | `{Boolean\|String}` | `false` | Export Classnames in CamelCase |
| **[`importLoaders`](#importloaders)** | `{Number}` | `0` | Number of loaders applied before CSS loader |
| **[`exportOnlyLocals`](#exportonlylocals)** | `{Boolean}` | `false` | Export only locals |
### `url`
Type: `Boolean|Function`
Default: `true`
Control `url()` resolving. Absolute URLs and root-relative URLs are not resolving.
Examples resolutions:
```
url(image.png) => require('./image.png')
url('image.png') => require('./image.png')
url(./image.png) => require('./image.png')
url('./image.png') => require('./image.png')
url('http://dontwritehorriblecode.com/2112.png') => require('http://dontwritehorriblecode.com/2112.png')
image-set(url('image2x.png') 1x, url('image1x.png') 2x) => require('./image1x.png') and require('./image2x.png')
```
To import assets from a `node_modules` path (include `resolve.modules`) and for `alias`, prefix it with a `~`:
```
url(~module/image.png) => require('module/image.png')
url('~module/image.png') => require('module/image.png')
url(~aliasDirectory/image.png) => require('otherDirectory/image.png')
```
#### `Boolean`
Enable/disable `url()` resolving.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: true,
},
},
],
},
};
```
#### `Function`
Allow to filter `url()`. All filtered `url()` will not be resolved (left in the code as they were written).
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
url: (url, resourcePath) => {
// resourcePath - path to css file
// `url()` with `img.png` stay untouched
return url.includes('img.png');
},
},
},
],
},
};
```
### `import`
Type: `Boolean`
Default: `true`
Control `@import` resolving. Absolute urls in `@import` will be moved in runtime code.
Examples resolutions:
```
@import 'style.css' => require('./style.css')
@import url(style.css) => require('./style.css')
@import url('style.css') => require('./style.css')
@import './style.css' => require('./style.css')
@import url(./style.css) => require('./style.css')
@import url('./style.css') => require('./style.css')
@import url('http://dontwritehorriblecode.com/style.css') => @import url('http://dontwritehorriblecode.com/style.css') in runtime
```
To import styles from a `node_modules` path (include `resolve.modules`) and for `alias`, prefix it with a `~`:
```
@import url(~module/style.css) => require('module/style.css')
@import url('~module/style.css') => require('module/style.css')
@import url(~aliasDirectory/style.css) => require('otherDirectory/style.css')
```
#### `Boolean`
Enable/disable `@import` resolving.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
import: true,
},
},
],
},
};
```
#### `Function`
Allow to filter `@import`. All filtered `@import` will not be resolved (left in the code as they were written).
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
import: (parsedImport, resourcePath) => {
// parsedImport.url - url of `@import`
// parsedImport.media - media query of `@import`
// resourcePath - path to css file
// `@import` with `style.css` stay untouched
return parsedImport.url.includes('style.css');
},
},
},
],
},
};
```
### [`modules`](https://github.com/css-modules/css-modules)
Type: `Boolean|String`
Default: `false`
The `modules` option enables/disables the **CSS Modules** spec and setup basic behaviour.
| Name | Type | Description |
| :------------: | :---------: | :------------------------------------------------------------------------------------------------------------------------------- |
| **`true`** | `{Boolean}` | Enables local scoped CSS by default (use **local** mode by default) |
| **`false`** | `{Boolean}` | Disable the **CSS Modules** spec, all **CSS Modules** features (like `@value`, `:local`, `:global` and `composes`) will not work |
| **`'local'`** | `{String}` | Enables local scoped CSS by default (same as `true` value) |
| **`'global'`** | `{String}` | Enables global scoped CSS by default |
Using `false` value increase performance because we avoid parsing **CSS Modules** features, it will be useful for developers who use vanilla css or use other technologies.
You can read about **modes** below.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
},
},
],
},
};
```
##### `Scope`
Using `local` value requires you to specify `:global` classes.
Using `global` value requires you to specify `:local` classes.
You can find more information [here](https://github.com/css-modules/css-modules).
Styles can be locally scoped to avoid globally scoping styles.
The syntax `:local(.className)` can be used to declare `className` in the local scope. The local identifiers are exported by the module.
With `:local` (without brackets) local mode can be switched on for this selector.
The `:global(.className)` nocation can be used to declare an explicit global selector.
With `:global` (without brackets) global mode can be switched on for this selector.
The loader replaces local selectors with unique identifiers. The chosen unique identifiers are exported by the module.
```css
:local(.className) {
background: red;
}
:local .className {
color: green;
}
:local(.className .subClass) {
color: green;
}
:local .className .subClass :global(.global-class-name) {
color: blue;
}
```
```css
._23_aKvs-b8bW2Vg3fwHozO {
background: red;
}
._23_aKvs-b8bW2Vg3fwHozO {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 {
color: green;
}
._23_aKvs-b8bW2Vg3fwHozO ._13LGdX8RMStbBE9w-t0gZ1 .global-class-name {
color: blue;
}
```
> ️ Identifiers are exported
```js
exports.locals = {
className: '_23_aKvs-b8bW2Vg3fwHozO',
subClass: '_13LGdX8RMStbBE9w-t0gZ1',
};
```
CamelCase is recommended for local selectors. They are easier to use within the imported JS module.
You can use `:local(#someId)`, but this is not recommended. Use classes instead of ids.
##### `Composing`
When declaring a local classname you can compose a local class from another local classname.
```css
:local(.className) {
background: red;
color: yellow;
}
:local(.subClass) {
composes: className;
background: blue;
}
```
This doesn't result in any change to the CSS itself but exports multiple classnames.
```js
exports.locals = {
className: '_23_aKvs-b8bW2Vg3fwHozO',
subClass: '_13LGdX8RMStbBE9w-t0gZ1 _23_aKvs-b8bW2Vg3fwHozO',
};
```
```css
._23_aKvs-b8bW2Vg3fwHozO {
background: red;
color: yellow;
}
._13LGdX8RMStbBE9w-t0gZ1 {
background: blue;
}
```
##### `Importing`
To import a local classname from another module.
```css
:local(.continueButton) {
composes: button from 'library/button.css';
background: red;
}
```
```css
:local(.nameEdit) {
composes: edit highlight from './edit.css';
background: red;
}
```
To import from multiple modules use multiple `composes:` rules.
```css
:local(.className) {
composes: edit hightlight from './edit.css';
composes: button from 'module/button.css';
composes: classFromThisModule;
background: red;
}
```
### `localIdentName`
Type: `String`
Default: `[hash:base64]`
You can configure the generated ident with the `localIdentName` query parameter.
See [loader-utils's documentation](https://github.com/webpack/loader-utils#interpolatename) for more information on options.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
},
},
],
},
};
```
### `context`
Type: `String`
Default: `undefined`
Allow to redefine basic loader context for local ident name.
By default we use `rootContext` of loader.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
context: path.resolve(__dirname, 'context'),
},
},
],
},
};
```
### `hashPrefix`
Type: `String`
Default: `undefined`
Allow to add custom hash to generate more unique classes.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
hashPrefix: 'hash',
},
},
],
},
};
```
### `getLocalIdent`
Type: `Function`
Default: `undefined`
You can also specify the absolute path to your custom `getLocalIdent` function to generate classname based on a different schema.
By default we use built-in function to generate a classname.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
modules: true,
getLocalIdent: (context, localIdentName, localName, options) => {
return 'whatever_random_class_name';
},
},
},
],
},
};
```
### `sourceMap`
Type: `Boolean`
Default: `false`
To include source maps set the `sourceMap` option.
I.e. the `mini-css-extract-plugin` can handle them.
They are not enabled by default because they expose a runtime overhead and increase in bundle size (JS source maps do not). In addition to that relative paths are buggy and you need to use an absolute public path which includes the server URL.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
};
```
### `camelCase`
Type: `Boolean|String`
Default: `false`
By default, the exported JSON keys mirror the class names. If you want to camelize class names (useful in JS), pass the query parameter `camelCase` to css-loader.
| Name | Type | Description |
| :----------------: | :---------: | :----------------------------------------------------------------------------------------------------------------------- |
| **`false`** | `{Boolean}` | Class names will be camelized, the original class name will not to be removed from the locals |
| **`true`** | `{Boolean}` | Class names will be camelized |
| **`'dashes'`** | `{String}` | Only dashes in class names will be camelized |
| **`'only'`** | `{String}` | Introduced in `0.27.1`. Class names will be camelized, the original class name will be removed from the locals |
| **`'dashesOnly'`** | `{String}` | Introduced in `0.27.1`. Dashes in class names will be camelized, the original class name will be removed from the locals |
**file.css**
```css
.class-name {
}
```
**file.js**
```js
import { className } from 'file.css';
```
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
camelCase: true,
},
},
],
},
};
```
### `importLoaders`
Type: `Number`
Default: `0`
The option `importLoaders` allows you to configure how many loaders before `css-loader` should be applied to `@import`ed resources.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2, // 0 => no loaders (default); 1 => postcss-loader; 2 => postcss-loader, sass-loader
},
},
'postcss-loader',
'sass-loader',
],
},
],
},
};
```
This may change in the future when the module system (i. e. webpack) supports loader matching by origin.
### `exportOnlyLocals`
Type: `Boolean`
Default: `false`
Export only locals (**useful** when you use **css modules**).
For pre-rendering with `mini-css-extract-plugin` you should use this option instead of `style-loader!css-loader` **in the pre-rendering bundle**.
It doesn't embed CSS but only exports the identifier mappings.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
loader: 'css-loader',
options: {
exportOnlyLocals: true,
},
},
],
},
};
```
## Examples
### Assets
The following `webpack.config.js` can load CSS files, embed small PNG/JPG/GIF/SVG images as well as fonts as [Data URLs](https://tools.ietf.org/html/rfc2397) and copy larger files to the output directory.
**webpack.config.js**
```js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 10000,
},
},
],
},
};
```
### Extract
For production builds it's recommended to extract the CSS from your bundle being able to use parallel loading of CSS/JS resources later on.
- This can be achieved by using the [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) to extract the CSS when running in production mode.
- As an alternative, if seeking better development performance and css outputs that mimic production. [extract-css-chunks-webpack-plugin](https://github.com/faceyspacey/extract-css-chunks-webpack-plugin) offers a hot module reload friendly, extended version of mini-css-extract-plugin. HMR real CSS files in dev, works like mini-css in non-dev
## Contributing
Please take a moment to read our contributing guidelines if you haven't yet done so.
[CONTRIBUTING](./.github/CONTRIBUTING.md)
## License
[MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/css-loader.svg
[npm-url]: https://npmjs.com/package/css-loader
[node]: https://img.shields.io/node/v/css-loader.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/css-loader.svg
[deps-url]: https://david-dm.org/webpack-contrib/css-loader
[tests]: https://img.shields.io/circleci/project/github/webpack-contrib/css-loader.svg
[tests-url]: https://circleci.com/gh/webpack-contrib/css-loader
[cover]: https://codecov.io/gh/webpack-contrib/css-loader/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/css-loader
[chat]: https://badges.gitter.im/webpack/webpack.svg
[chat-url]: https://gitter.im/webpack/webpack
[size]: https://packagephobia.now.sh/badge?p=css-loader
[size-url]: https://packagephobia.now.sh/result?p=css-loader
@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class CssSyntaxError extends Error {
constructor(error) {
super(error);
const {
reason,
line,
column
} = error;
this.name = 'CssSyntaxError'; // Based on https://github.com/postcss/postcss/blob/master/lib/css-syntax-error.es6#L132
// We don't need `plugin` and `file` properties.
this.message = `${this.name}\n\n`;
if (typeof line !== 'undefined') {
this.message += `(${line}:${column}) `;
}
this.message += `${reason}`;
const code = error.showSourceCode();
if (code) {
this.message += `\n\n${code}\n`;
} // We don't need stack https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
this.stack = false;
}
}
exports.default = CssSyntaxError;
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
class Warning extends Error {
constructor(warning) {
super(warning);
const {
text,
line,
column
} = warning;
this.name = 'Warning'; // Based on https://github.com/postcss/postcss/blob/master/lib/warning.es6#L74
// We don't need `plugin` properties.
this.message = `${this.name}\n\n`;
if (typeof line !== 'undefined') {
this.message += `(${line}:${column}) `;
}
this.message += `${text}`; // We don't need stack https://github.com/postcss/postcss/blob/master/docs/guidelines/runner.md#31-dont-show-js-stack-for-csssyntaxerror
this.stack = false;
}
}
exports.default = Warning;
@@ -0,0 +1,5 @@
"use strict";
const loader = require('./index');
module.exports = loader.default;
+260
View File
@@ -0,0 +1,260 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = loader;
var _schemaUtils = _interopRequireDefault(require("schema-utils"));
var _postcss = _interopRequireDefault(require("postcss"));
var _package = _interopRequireDefault(require("postcss/package.json"));
var _postcssModulesLocalByDefault = _interopRequireDefault(require("postcss-modules-local-by-default"));
var _postcssModulesExtractImports = _interopRequireDefault(require("postcss-modules-extract-imports"));
var _postcssModulesScope = _interopRequireDefault(require("postcss-modules-scope"));
var _postcssModulesValues = _interopRequireDefault(require("postcss-modules-values"));
var _loaderUtils = require("loader-utils");
var _normalizePath = _interopRequireDefault(require("normalize-path"));
var _options = _interopRequireDefault(require("./options.json"));
var _plugins = require("./plugins");
var _utils = require("./utils");
var _Warning = _interopRequireDefault(require("./Warning"));
var _CssSyntaxError = _interopRequireDefault(require("./CssSyntaxError"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
function loader(content, map, meta) {
const options = (0, _loaderUtils.getOptions)(this) || {};
(0, _schemaUtils.default)(_options.default, options, 'CSS Loader');
const callback = this.async();
const sourceMap = options.sourceMap || false;
/* eslint-disable no-param-reassign */
if (sourceMap) {
if (map) {
// Some loader emit source map as string
// Strip any JSON XSSI avoidance prefix from the string (as documented in the source maps specification), and then parse the string as JSON.
if (typeof map === 'string') {
map = JSON.parse(map.replace(/^\)]}'[^\n]*\n/, ''));
} // Source maps should use forward slash because it is URLs (https://github.com/mozilla/source-map/issues/91)
// We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
if (map.file) {
map.file = (0, _normalizePath.default)(map.file);
}
if (map.sourceRoot) {
map.sourceRoot = (0, _normalizePath.default)(map.sourceRoot);
}
if (map.sources) {
map.sources = map.sources.map(source => (0, _normalizePath.default)(source));
}
}
} else {
// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
map = null;
}
/* eslint-enable no-param-reassign */
// Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
if (meta) {
const {
ast
} = meta;
if (ast && ast.type === 'postcss' && ast.version === _package.default.version) {
// eslint-disable-next-line no-param-reassign
content = ast.root;
}
}
const plugins = [];
if (options.modules) {
const loaderContext = this;
const mode = typeof options.modules === 'boolean' ? 'local' : options.modules;
plugins.push(_postcssModulesValues.default, (0, _postcssModulesLocalByDefault.default)({
mode
}), (0, _postcssModulesExtractImports.default)(), (0, _postcssModulesScope.default)({
generateScopedName: function generateScopedName(exportName) {
const localIdentName = options.localIdentName || '[hash:base64]';
const customGetLocalIdent = options.getLocalIdent || _utils.getLocalIdent;
return customGetLocalIdent(loaderContext, localIdentName, exportName, {
regExp: options.localIdentRegExp,
hashPrefix: options.hashPrefix || '',
context: options.context
});
}
}));
}
if (options.import !== false) {
plugins.push((0, _plugins.importParser)({
filter: (0, _utils.getFilter)(options.import, this.resourcePath)
}));
}
if (options.url !== false) {
plugins.push((0, _plugins.urlParser)({
filter: (0, _utils.getFilter)(options.url, this.resourcePath, value => (0, _loaderUtils.isUrlRequest)(value))
}));
}
plugins.push((0, _plugins.icssParser)());
(0, _postcss.default)(plugins).process(content, {
from: (0, _loaderUtils.getRemainingRequest)(this).split('!').pop(),
to: (0, _loaderUtils.getCurrentRequest)(this).split('!').pop(),
map: options.sourceMap ? {
prev: map,
inline: false,
annotation: false
} : null
}).then(result => {
result.warnings().forEach(warning => this.emitWarning(new _Warning.default(warning)));
const messages = result.messages || []; // Run other loader (`postcss-loader`, `sass-loader` and etc) for importing CSS
const importUrlPrefix = (0, _utils.getImportPrefix)(this, options.importLoaders); // Prepare replacer to change from `___CSS_LOADER_IMPORT___INDEX___` to `require('./file.css').locals`
const importItemReplacer = placeholder => {
const match = _utils.placholderRegExps.importItem.exec(placeholder);
const idx = Number(match[1]);
const message = messages.find( // eslint-disable-next-line no-shadow
message => message.type === 'icss-import' && message.item && message.item.index === idx);
if (!message) {
return placeholder;
}
const {
item
} = message;
const importUrl = importUrlPrefix + (0, _loaderUtils.urlToRequest)(item.url);
if (options.exportOnlyLocals) {
return `" + require(${(0, _loaderUtils.stringifyRequest)(this, importUrl)})[${JSON.stringify(item.export)}] + "`;
}
return `" + require(${(0, _loaderUtils.stringifyRequest)(this, importUrl)}).locals[${JSON.stringify(item.export)}] + "`;
};
const exports = messages.filter(message => message.type === 'export').reduce((accumulator, message) => {
const {
key,
value
} = message.item;
let valueAsString = JSON.stringify(value);
valueAsString = valueAsString.replace(_utils.placholderRegExps.importItemG, importItemReplacer);
function addEntry(k) {
accumulator.push(`\t${JSON.stringify(k)}: ${valueAsString}`);
}
let targetKey;
switch (options.camelCase) {
case true:
addEntry(key);
targetKey = (0, _utils.camelCase)(key);
if (targetKey !== key) {
addEntry(targetKey);
}
break;
case 'dashes':
addEntry(key);
targetKey = (0, _utils.dashesCamelCase)(key);
if (targetKey !== key) {
addEntry(targetKey);
}
break;
case 'only':
addEntry((0, _utils.camelCase)(key));
break;
case 'dashesOnly':
addEntry((0, _utils.dashesCamelCase)(key));
break;
default:
addEntry(key);
break;
}
return accumulator;
}, []);
if (options.exportOnlyLocals) {
return callback(null, exports.length > 0 ? `module.exports = {\n${exports.join(',\n')}\n};` : '');
}
const imports = messages.filter(message => message.type === 'import').map(message => {
const {
url
} = message.item;
const media = message.item.media || '';
if (!(0, _loaderUtils.isUrlRequest)(url)) {
return `exports.push([module.id, ${JSON.stringify(`@import url(${url});`)}, ${JSON.stringify(media)}]);`;
}
const importUrl = importUrlPrefix + (0, _loaderUtils.urlToRequest)(url);
return `exports.i(require(${(0, _loaderUtils.stringifyRequest)(this, importUrl)}), ${JSON.stringify(media)});`;
}, this);
let cssAsString = JSON.stringify(result.css).replace(_utils.placholderRegExps.importItemG, importItemReplacer); // Helper for ensuring valid CSS strings from requires
let hasUrlEscapeHelper = false;
messages.filter(message => message.type === 'url').forEach(message => {
if (!hasUrlEscapeHelper) {
imports.push(`var urlEscape = require(${(0, _loaderUtils.stringifyRequest)(this, require.resolve('./runtime/url-escape.js'))});`);
hasUrlEscapeHelper = true;
}
const {
item
} = message;
const {
url,
placeholder,
needQuotes
} = item; // Remove `#hash` and `?#hash` from `require`
const [normalizedUrl, singleQuery, hashValue] = url.split(/(\?)?#/);
const hash = singleQuery || hashValue ? `"${singleQuery ? '?' : ''}${hashValue ? `#${hashValue}` : ''}"` : '';
imports.push(`var ${placeholder} = urlEscape(require(${(0, _loaderUtils.stringifyRequest)(this, (0, _loaderUtils.urlToRequest)(normalizedUrl))})${hash ? ` + ${hash}` : ''}${needQuotes ? ', true' : ''});`);
cssAsString = cssAsString.replace(new RegExp(placeholder, 'g'), () => `" + ${placeholder} + "`);
});
const runtimeCode = `exports = module.exports = require(${(0, _loaderUtils.stringifyRequest)(this, require.resolve('./runtime/api'))})(${!!sourceMap});\n`;
const importCode = imports.length > 0 ? `// Imports\n${imports.join('\n')}\n\n` : '';
const moduleCode = `// Module\nexports.push([module.id, ${cssAsString}, ""${result.map ? `,${result.map}` : ''}]);\n\n`;
const exportsCode = exports.length > 0 ? `// Exports\nexports.locals = {\n${exports.join(',\n')}\n};` : ''; // Embed runtime
return callback(null, runtimeCode + importCode + moduleCode + exportsCode);
}).catch(error => {
callback(error.name === 'CssSyntaxError' ? new _CssSyntaxError.default(error) : error);
});
}
@@ -0,0 +1,93 @@
{
"additionalProperties": false,
"properties": {
"url": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"import": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"modules": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"enum": ["local", "global"]
}
]
},
"localIdentName": {
"type": "string"
},
"localIdentRegExp": {
"anyOf": [
{
"type": "string"
},
{
"instanceof": "RegExp"
}
]
},
"context": {
"type": "string"
},
"hashPrefix": {
"type": "string"
},
"getLocalIdent": {
"anyOf": [
{
"type": "boolean"
},
{
"instanceof": "Function"
}
]
},
"sourceMap": {
"type": "boolean"
},
"camelCase": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "string",
"enum": ["dashes", "only", "dashesOnly"]
}
]
},
"importLoaders": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "number"
}
]
},
"exportOnlyLocals": {
"type": "boolean"
}
},
"type": "object"
}
@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "importParser", {
enumerable: true,
get: function () {
return _postcssImportParser.default;
}
});
Object.defineProperty(exports, "icssParser", {
enumerable: true,
get: function () {
return _postcssIcssParser.default;
}
});
Object.defineProperty(exports, "urlParser", {
enumerable: true,
get: function () {
return _postcssUrlParser.default;
}
});
var _postcssImportParser = _interopRequireDefault(require("./postcss-import-parser"));
var _postcssIcssParser = _interopRequireDefault(require("./postcss-icss-parser"));
var _postcssUrlParser = _interopRequireDefault(require("./postcss-url-parser"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,101 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
var _icssUtils = require("icss-utils");
var _loaderUtils = _interopRequireDefault(require("loader-utils"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pluginName = 'postcss-icss-parser';
var _default = _postcss.default.plugin(pluginName, () => function process(css, result) {
const imports = {};
const icss = (0, _icssUtils.extractICSS)(css);
const exports = icss.icssExports;
Object.keys(icss.icssImports).forEach(key => {
const url = _loaderUtils.default.parseString(key);
Object.keys(icss.icssImports[key]).forEach(prop => {
const index = Object.keys(imports).length;
imports[`$${prop}`] = index;
result.messages.push({
pluginName,
type: 'icss-import',
item: {
url,
export: icss.icssImports[key][prop],
index
}
});
const alreadyIncluded = result.messages.find(message => message.pluginName === pluginName && message.type === 'import' && message.item.url === url && message.item.media === '');
if (alreadyIncluded) {
return;
}
result.messages.push({
pluginName,
type: 'import',
item: {
url,
media: ''
}
});
});
});
function replaceImportsInString(str) {
const tokens = (0, _postcssValueParser.default)(str);
tokens.walk(node => {
if (node.type !== 'word') {
return;
}
const token = node.value;
const importIndex = imports[`$${token}`];
if (typeof importIndex === 'number') {
// eslint-disable-next-line no-param-reassign
node.value = `___CSS_LOADER_IMPORT___${importIndex}___`;
}
});
return tokens.toString();
} // Replace tokens in declarations
css.walkDecls(decl => {
// eslint-disable-next-line no-param-reassign
decl.value = replaceImportsInString(decl.value.toString());
}); // Replace tokens in at-rules
css.walkAtRules(atrule => {
// Due reusing `ast` from `postcss-loader` some plugins may lack
// `params` property, we need to account for this possibility
if (atrule.params) {
// eslint-disable-next-line no-param-reassign
atrule.params = replaceImportsInString(atrule.params.toString());
}
}); // Replace tokens in export
Object.keys(exports).forEach(exportName => {
result.messages.push({
pluginName,
type: 'export',
item: {
key: exportName,
value: replaceImportsInString(exports[exportName])
}
});
});
});
exports.default = _default;
@@ -0,0 +1,110 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pluginName = 'postcss-import-parser';
function getArg(nodes) {
return nodes.length !== 0 && nodes[0].type === 'string' ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
}
function getUrl(node) {
if (node.type === 'function' && node.value.toLowerCase() === 'url') {
return getArg(node.nodes);
}
if (node.type === 'string') {
return node.value;
}
return null;
}
function parseImport(params) {
const {
nodes
} = (0, _postcssValueParser.default)(params);
if (nodes.length === 0) {
return null;
}
const url = getUrl(nodes[0]);
if (!url || url.trim().length === 0) {
return null;
}
return {
url,
media: _postcssValueParser.default.stringify(nodes.slice(1)).trim().toLowerCase()
};
}
function walkAtRules(css, result, filter) {
const items = [];
css.walkAtRules(/^import$/i, atRule => {
// Convert only top-level @import
if (atRule.parent.type !== 'root') {
return;
}
if (atRule.nodes) {
result.warn("It looks like you didn't end your @import statement correctly. " + 'Child nodes are attached to it.', {
node: atRule
});
return;
}
const parsed = parseImport(atRule.params);
if (!parsed) {
// eslint-disable-next-line consistent-return
return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
node: atRule
});
}
if (filter && !filter(parsed)) {
return;
}
atRule.remove();
const {
url,
media
} = parsed;
items.push({
url,
media
});
});
return items;
}
function uniq(array) {
return array.reduce((acc, d) => !acc.find(el => el.url === d.url && el.media === d.media) ? [...acc, d] : acc, []);
}
var _default = _postcss.default.plugin(pluginName, (options = {}) => function process(css, result) {
const traversed = walkAtRules(css, result, options.filter);
const paths = uniq(traversed);
paths.forEach(item => {
result.messages.push({
pluginName,
type: 'import',
item
});
});
});
exports.default = _default;
@@ -0,0 +1,159 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const pluginName = 'postcss-url-parser';
const isUrlFunc = /url/i;
const isImageSetFunc = /^(?:-webkit-)?image-set$/i;
const needParseDecl = /(?:url|(?:-webkit-)?image-set)\(/i;
function getNodeFromUrlFunc(node) {
return node.nodes && node.nodes[0];
}
function getUrlFromUrlFunc(node) {
return node.nodes.length !== 0 && node.nodes[0].type === 'string' ? node.nodes[0].value : _postcssValueParser.default.stringify(node.nodes);
}
function walkUrls(parsed, callback) {
parsed.walk(node => {
if (node.type !== 'function') {
return;
}
if (isUrlFunc.test(node.value)) {
callback(getNodeFromUrlFunc(node), getUrlFromUrlFunc(node), false); // Do not traverse inside `url`
// eslint-disable-next-line consistent-return
return false;
}
if (isImageSetFunc.test(node.value)) {
node.nodes.forEach(nNode => {
if (nNode.type === 'function' && isUrlFunc.test(nNode.value)) {
callback(getNodeFromUrlFunc(nNode), getUrlFromUrlFunc(nNode), false);
}
if (nNode.type === 'string') {
callback(nNode, nNode.value, true);
}
}); // Do not traverse inside `image-set`
// eslint-disable-next-line consistent-return
return false;
}
});
}
function walkDeclsWithUrl(css, result, filter) {
const items = [];
css.walkDecls(decl => {
if (!needParseDecl.test(decl.value)) {
return;
}
const parsed = (0, _postcssValueParser.default)(decl.value);
const urls = [];
walkUrls(parsed, (node, url, needQuotes) => {
if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
result.warn(`Unable to find uri in '${decl.toString()}'`, {
node: decl
});
return;
}
if (filter && !filter(url)) {
return;
}
urls.push({
url,
needQuotes
});
});
if (urls.length === 0) {
return;
}
items.push({
decl,
parsed,
urls
});
});
return items;
}
function uniqWith(array, comparator) {
return array.reduce((acc, d) => !acc.some(item => comparator(d, item)) ? [...acc, d] : acc, []);
}
function flatten(array) {
return array.reduce((a, b) => a.concat(b), []);
}
function isEqual(value, other) {
return value.url === other.url && value.needQuotes === other.needQuotes;
}
var _default = _postcss.default.plugin(pluginName, (options = {}) => function process(css, result) {
const traversed = walkDeclsWithUrl(css, result, options.filter);
const paths = uniqWith(flatten(traversed.map(item => item.urls)), isEqual);
if (paths.length === 0) {
return;
}
const placeholders = [];
paths.forEach((path, index) => {
const placeholder = `___CSS_LOADER_URL___${index}___`;
const {
url,
needQuotes
} = path;
placeholders.push({
placeholder,
path
});
result.messages.push({
pluginName,
type: 'url',
item: {
url,
placeholder,
needQuotes
}
});
});
traversed.forEach(item => {
walkUrls(item.parsed, (node, url, needQuotes) => {
const value = placeholders.find(placeholder => placeholder.path.url === url && placeholder.path.needQuotes === needQuotes);
if (!value) {
return;
}
const {
placeholder
} = value; // eslint-disable-next-line no-param-reassign
node.type = 'word'; // eslint-disable-next-line no-param-reassign
node.value = placeholder;
}); // eslint-disable-next-line no-param-reassign
item.decl.value = item.parsed.toString();
});
});
exports.default = _default;
@@ -0,0 +1,85 @@
"use strict";
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function (useSourceMap) {
var list = []; // return the list of modules as css string
list.toString = function toString() {
return this.map(function (item) {
var content = cssWithMappingToString(item, useSourceMap);
if (item[2]) {
return '@media ' + item[2] + '{' + content + '}';
} else {
return content;
}
}).join('');
}; // import a list of modules into the list
list.i = function (modules, mediaQuery) {
if (typeof modules === 'string') {
modules = [[null, modules, '']];
}
var alreadyImportedModules = {};
for (var i = 0; i < this.length; i++) {
var id = this[i][0];
if (id != null) {
alreadyImportedModules[id] = true;
}
}
for (i = 0; i < modules.length; i++) {
var item = modules[i]; // skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if (item[0] == null || !alreadyImportedModules[item[0]]) {
if (mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if (mediaQuery) {
item[2] = '(' + item[2] + ') and (' + mediaQuery + ')';
}
list.push(item);
}
}
};
return list;
};
function cssWithMappingToString(item, useSourceMap) {
var content = item[1] || '';
var cssMapping = item[3];
if (!cssMapping) {
return content;
}
if (useSourceMap && typeof btoa === 'function') {
var sourceMapping = toComment(cssMapping);
var sourceURLs = cssMapping.sources.map(function (source) {
return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */';
});
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
}
return [content].join('\n');
} // Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
// eslint-disable-next-line no-undef
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
return '/*# ' + data + ' */';
}
@@ -0,0 +1,20 @@
"use strict";
module.exports = function escape(url, needQuotes) {
if (typeof url !== 'string') {
return url;
} // If url is already wrapped in quotes, remove them
if (/^['"].*['"]$/.test(url)) {
url = url.slice(1, -1);
} // Should url be wrapped?
// See https://drafts.csswg.org/css-values-3/#urls
if (/["'() \t\n]/.test(url) || needQuotes) {
return '"' + url.replace(/"/g, '\\"').replace(/\n/g, '\\n') + '"';
}
return url;
};
@@ -0,0 +1,97 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getImportPrefix = getImportPrefix;
exports.getLocalIdent = getLocalIdent;
exports.camelCase = camelCase;
exports.dashesCamelCase = dashesCamelCase;
exports.getFilter = getFilter;
exports.placholderRegExps = void 0;
var _path = _interopRequireDefault(require("path"));
var _camelcase = _interopRequireDefault(require("camelcase"));
var _loaderUtils = _interopRequireDefault(require("loader-utils"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
/* eslint-disable line-comment-position */
const placholderRegExps = {
importItemG: /___CSS_LOADER_IMPORT___([0-9]+)___/g,
importItem: /___CSS_LOADER_IMPORT___([0-9]+)___/
};
exports.placholderRegExps = placholderRegExps;
function getImportPrefix(loaderContext, importLoaders) {
if (importLoaders === false) {
return '';
}
const numberImportedLoaders = parseInt(importLoaders, 10) || 0;
const loadersRequest = loaderContext.loaders.slice(loaderContext.loaderIndex, loaderContext.loaderIndex + 1 + numberImportedLoaders).map(x => x.request).join('!');
return `-!${loadersRequest}!`;
}
function camelCase(str) {
return (0, _camelcase.default)(str);
}
function dashesCamelCase(str) {
return str.replace(/-+(\w)/g, (match, firstLetter) => firstLetter.toUpperCase());
}
const whitespace = '[\\x20\\t\\r\\n\\f]';
const unescapeRegExp = new RegExp(`\\\\([\\da-f]{1,6}${whitespace}?|(${whitespace})|.)`, 'ig');
function unescape(str) {
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
const high = `0x${escaped}` - 0x10000; // NaN means non-codepoint
// Workaround erroneous numeric interpretation of +"0x"
// eslint-disable-next-line no-self-compare
return high !== high || escapedWhitespace ? escaped : high < 0 ? // BMP codepoint
String.fromCharCode(high + 0x10000) : // Supplemental Plane codepoint (surrogate pair)
// eslint-disable-next-line no-bitwise
String.fromCharCode(high >> 10 | 0xd800, high & 0x3ff | 0xdc00);
});
}
function getLocalIdent(loaderContext, localIdentName, localName, options) {
if (!options.context) {
// eslint-disable-next-line no-param-reassign
options.context = loaderContext.rootContext;
}
const request = _path.default.relative(options.context, loaderContext.resourcePath).replace(/\\/g, '/'); // eslint-disable-next-line no-param-reassign
options.content = `${options.hashPrefix + request}+${unescape(localName)}`; // eslint-disable-next-line no-param-reassign
localIdentName = localIdentName.replace(/\[local\]/gi, localName);
const hash = _loaderUtils.default.interpolateName(loaderContext, localIdentName, options);
return hash.replace(new RegExp('[^a-zA-Z0-9\\-_\u00A0-\uFFFF]', 'g'), '-').replace(/^((-?[0-9])|--)/, '_$1');
}
function getFilter(filter, resourcePath, defaultFilter = null) {
return content => {
if (defaultFilter && !defaultFilter(content)) {
return false;
}
if (typeof filter === 'function') {
return !filter(content, resourcePath);
}
return true;
};
}
@@ -0,0 +1,134 @@
# Change Log
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.
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)
### Features
* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
<a name="0.4.7"></a>
## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)
### Bug Fixes
* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))
<a name="0.4.6"></a>
## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)
### Bug Fixes
* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)
### Bug Fixes
* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)
### Bug Fixes
* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)
### Bug Fixes
* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)
### Bug Fixes
* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)
### Bug Fixes
* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
<a name="0.4.0"></a>
# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)
### Features
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
<a name="0.3.0"></a>
# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)
### Features
* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)
### Bug Fixes
* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)
<a name="0.1.0"></a>
# 0.1.0 (2017-03-07)
### Features
* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))
# Change Log
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.
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,149 @@
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![test][test]][test-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/docs/logo.png">
</a>
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
<h1>Schema Utils</h1>
</div>
<h2 align="center">Install</h2>
```bash
npm i schema-utils
```
<h2 align="center">Usage</h2>
### `validateOptions`
**`schema.json`**
```js
{
"type": "object",
"properties": {
// Options...
},
"additionalProperties": false
}
```
#### Error Messages (Custom)
**`schema.json`**
```js
{
"type": "object",
"properties": {
"option": {
"type": [ "boolean" ]
}
},
// Overrides the default err.message for option
"errorMessage": {
"option": "should be {Boolean} (https:/github.com/org/repo#anchor)"
}
"additionalProperties": false
}
```
```js
import schema from 'path/to/schema.json'
import validateOptions from 'schema-utils'
validateOptions(schema, options, 'Loader/Plugin Name')
```
<h2 align="center">Examples</h2>
**schema.json**
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"test": {
"anyOf": [
{ "type": "array" },
{ "type": "string" },
{ "instanceof": "RegExp" }
]
},
"transform": {
"instanceof": "Function"
},
"sourceMap": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
### `Loader`
```js
import { getOptions } from 'loader-utils'
import validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
function loader (src, map) {
const options = getOptions(this) || {}
validateOptions(schema, options, 'Loader Name')
// Code...
}
```
### `Plugin`
```js
import validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
class Plugin {
constructor (options) {
validateOptions(schema, options, 'Plugin Name')
this.options = options
}
apply (compiler) {
// Code...
}
}
```
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/schema-utils.svg
[deps-url]: https://david-dm.org/webpack-contrib/schema-utils
[test]: http://img.shields.io/travis/webpack-contrib/schema-utils.svg
[test-url]: https://travis-ci.org/webpack-contrib/schema-utils
[cover]: https://codecov.io/gh/webpack-contrib/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/schema-utils
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
@@ -0,0 +1,41 @@
{
"name": "schema-utils",
"version": "1.0.0",
"description": "webpack Validation Utils",
"main": "src/index.js",
"files": [
"src"
],
"engines": {
"node": ">= 4"
},
"scripts": {
"lint": "eslint --cache src test",
"test": "jest --env node --verbose --coverage",
"clean": "del-cli coverage",
"commits": "commitlint --from $(git rev-list --tags --max-count=1)",
"release": "npm run commits && standard-version"
},
"dependencies": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
},
"devDependencies": {
"@commitlint/cli": "^7.0.0",
"@commitlint/config-conventional": "^7.0.0",
"@webpack-contrib/eslint-config-webpack": "^2.0.0",
"del-cli": "^1.0.0",
"eslint": "^5.0.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-prettier": "^2.0.0",
"jest": "^21.0.0",
"prettier": "^1.0.0",
"standard-version": "^4.0.0"
},
"author": "webpack Contrib (https://github.com/webpack-contrib)",
"bugs": "https://github.com/webpack-contrib/schema-utils/issues",
"homepage": "https://github.com/webpack-contrib/schema-utils",
"repository": "https://github.com/webpack-contrib/schema-utils",
"license": "MIT"
}
@@ -0,0 +1,30 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
class ValidationError extends Error {
constructor(errors, name) {
super();
this.name = 'ValidationError';
this.message = `${name || ''} Invalid Options\n\n`;
this.errors = errors.map((err) => {
err.dataPath = err.dataPath.replace(/\//g, '.');
return err;
});
this.errors.forEach((err) => {
this.message += `options${err.dataPath} ${err.message}\n`;
});
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = ValidationError;
@@ -0,0 +1,9 @@
/* eslint-disable
strict
*/
'use strict';
const validateOptions = require('./validateOptions');
module.exports = validateOptions;
@@ -0,0 +1,38 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
const fs = require('fs');
const path = require('path');
const Ajv = require('ajv');
const errors = require('ajv-errors');
const keywords = require('ajv-keywords');
const ValidationError = require('./ValidationError');
const ajv = new Ajv({
allErrors: true,
jsonPointers: true,
});
errors(ajv);
keywords(ajv, ['instanceof', 'typeof']);
const validateOptions = (schema, options, name) => {
if (typeof schema === 'string') {
schema = fs.readFileSync(path.resolve(schema), 'utf8');
schema = JSON.parse(schema);
}
if (!ajv.validate(schema, options)) {
throw new ValidationError(ajv.errors, name);
}
return true;
};
module.exports = validateOptions;
+128
View File
@@ -0,0 +1,128 @@
{
"name": "css-loader",
"version": "2.1.1",
"description": "css loader module for webpack",
"license": "MIT",
"repository": "webpack-contrib/css-loader",
"author": "Tobias Koppers @sokra",
"homepage": "https://github.com/webpack-contrib/css-loader",
"bugs": "https://github.com/webpack-contrib/css-loader/issues",
"main": "dist/cjs.js",
"engines": {
"node": ">= 6.9.0"
},
"scripts": {
"start": "npm run build -- -w",
"prebuild": "npm run clean",
"build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files",
"clean": "del-cli dist",
"commitlint": "commitlint",
"commitmsg": "commitlint -e $GIT_PARAMS",
"lint": "eslint --cache src test",
"prepublish": "npm run build",
"release": "standard-version",
"security": "npm audit",
"test:only": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage",
"pretest": "npm run lint",
"test": "npm run test:only",
"ci:lint": "npm run lint && npm run security",
"ci:test": "npm run test:only -- --runInBand",
"ci:coverage": "npm run test:coverage -- --runInBand",
"ci:lint:commits": "commitlint --from=origin/master --to=${CIRCLE_SHA1}",
"defaults": "webpack-defaults"
},
"files": [
"dist/",
"lib/",
"index.js"
],
"peerDependencies": {
"webpack": "^4.0.0"
},
"dependencies": {
"icss-utils": "^4.1.0",
"loader-utils": "^1.2.3",
"camelcase": "^5.2.0",
"normalize-path": "^3.0.0",
"postcss": "^7.0.14",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^2.0.6",
"postcss-modules-scope": "^2.1.0",
"postcss-modules-values": "^2.0.0",
"postcss-value-parser": "^3.3.0",
"schema-utils": "^1.0.0"
},
"devDependencies": {
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.6",
"@commitlint/cli": "^7.2.1",
"@commitlint/config-conventional": "^7.1.2",
"@webpack-contrib/defaults": "^3.0.0",
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
"babel-jest": "^24.1.0",
"cross-env": "^5.2.0",
"del": "^4.0.0",
"del-cli": "^1.1.0",
"eslint": "^5.9.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-prettier": "^3.0.0",
"file-loader": "^3.0.1",
"husky": "^1.2.0",
"jest": "^24.1.0",
"lint-staged": "^8.1.0",
"memory-fs": "^0.4.1",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.4.0",
"prettier": "^1.15.2",
"sass": "^1.15.1",
"sass-loader": "^7.1.0",
"standard-version": "^5.0.0",
"strip-ansi": "^5.0.0",
"webpack": "^4.26.1"
},
"keywords": [
"webpack",
"css",
"loader",
"url",
"import"
],
"babel": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "6.9.0"
},
"useBuiltIns": "usage"
}
]
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"prettier": {
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "always"
}
}
+6
View File
@@ -0,0 +1,6 @@
ISC License (ISC)
Copyright 2018 Glen Maddern
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+84
View File
@@ -0,0 +1,84 @@
[![Build Status](https://travis-ci.org/css-modules/icss-utils.svg)](https://travis-ci.org/css-modules/icss-utils)
# ICSS Utils
## replaceSymbols
Governs the way tokens are searched & replaced during the linking stage of ICSS loading.
This is broken into its own module in case the behaviour needs to be replicated in other PostCSS plugins
(i.e. [CSS Modules Values](https://github.com/css-modules/postcss-modules-values))
```js
import { replaceSymbols, replaceValueSymbols } from "icss-utils";
replaceSymbols(css, replacements);
replaceValueSymbols(string, replacements);
```
Where:
- `css` is the PostCSS tree you're working with
- `replacements` is an JS object of `symbol: "replacement"` pairs, where all occurrences of `symbol` are replaced with `replacement`.
A symbol is a string of alphanumeric, `-` or `_` characters. A replacement can be any string. They are replaced in the following places:
- In the value of a declaration, i.e. `color: my_symbol;` or `box-shadow: 0 0 blur spread shadow-color`
- In a media expression i.e. `@media small {}` or `@media screen and not-large {}`
## extractICSS(css, removeRules = true)
Extracts and remove (if removeRules is equal true) from PostCSS tree `:import` and `:export` statements.
```js
import postcss from "postcss";
import { extractICSS } from "icss-utils";
const css = postcss.parse(`
:import(colors) {
a: b;
}
:export {
c: d;
}
`);
extractICSS(css);
/*
{
icssImports: {
colors: {
a: 'b'
}
},
icssExports: {
c: 'd'
}
}
*/
```
## createICSSRules(icssImports, icssExports)
Converts icss imports and exports definitions to postcss ast
```js
createICSSRules(
{
colors: {
a: "b"
}
},
{
c: "d"
}
);
```
## License
ISC
---
Glen Maddern, Bogdan Chadkin and Evilebottnawi 2015-present.
@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _postcss = _interopRequireDefault(require("postcss"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const createImports = imports => {
return Object.keys(imports).map(path => {
const aliases = imports[path];
const declarations = Object.keys(aliases).map(key => _postcss.default.decl({
prop: key,
value: aliases[key],
raws: {
before: "\n "
}
}));
const hasDeclarations = declarations.length > 0;
const rule = _postcss.default.rule({
selector: `:import('${path}')`,
raws: {
after: hasDeclarations ? "\n" : ""
}
});
if (hasDeclarations) {
rule.append(declarations);
}
return rule;
});
};
const createExports = exports => {
const declarations = Object.keys(exports).map(key => _postcss.default.decl({
prop: key,
value: exports[key],
raws: {
before: "\n "
}
}));
if (declarations.length === 0) {
return [];
}
const rule = _postcss.default.rule({
selector: `:export`,
raws: {
after: "\n"
}
}).append(declarations);
return [rule];
};
const createICSSRules = (imports, exports) => [...createImports(imports), ...createExports(exports)];
var _default = createICSSRules;
exports.default = _default;
@@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const importPattern = /^:import\(("[^"]*"|'[^']*'|[^"']+)\)$/;
const getDeclsObject = rule => {
const object = {};
rule.walkDecls(decl => {
const before = decl.raws.before ? decl.raws.before.trim() : "";
object[before + decl.prop] = decl.value;
});
return object;
};
const extractICSS = (css, removeRules = true) => {
const icssImports = {};
const icssExports = {};
css.each(node => {
if (node.type === "rule") {
if (node.selector.slice(0, 7) === ":import") {
const matches = importPattern.exec(node.selector);
if (matches) {
const path = matches[1].replace(/'|"/g, "");
icssImports[path] = Object.assign(icssImports[path] || {}, getDeclsObject(node));
if (removeRules) {
node.remove();
}
}
}
if (node.selector === ":export") {
Object.assign(icssExports, getDeclsObject(node));
if (removeRules) {
node.remove();
}
}
}
});
return {
icssImports,
icssExports
};
};
var _default = extractICSS;
exports.default = _default;
+39
View File
@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "replaceValueSymbols", {
enumerable: true,
get: function get() {
return _replaceValueSymbols.default;
}
});
Object.defineProperty(exports, "replaceSymbols", {
enumerable: true,
get: function get() {
return _replaceSymbols.default;
}
});
Object.defineProperty(exports, "extractICSS", {
enumerable: true,
get: function get() {
return _extractICSS.default;
}
});
Object.defineProperty(exports, "createICSSRules", {
enumerable: true,
get: function get() {
return _createICSSRules.default;
}
});
var _replaceValueSymbols = _interopRequireDefault(require("./replaceValueSymbols.js"));
var _replaceSymbols = _interopRequireDefault(require("./replaceSymbols.js"));
var _extractICSS = _interopRequireDefault(require("./extractICSS.js"));
var _createICSSRules = _interopRequireDefault(require("./createICSSRules.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _replaceValueSymbols = _interopRequireDefault(require("./replaceValueSymbols.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const replaceSymbols = (css, replacements) => {
css.walk(node => {
if (node.type === "decl" && node.value) {
node.value = (0, _replaceValueSymbols.default)(node.value.toString(), replacements);
} else if (node.type === "rule" && node.selector) {
node.selector = (0, _replaceValueSymbols.default)(node.selector.toString(), replacements);
} else if (node.type === "atrule" && node.params) {
node.params = (0, _replaceValueSymbols.default)(node.params.toString(), replacements);
}
});
};
var _default = replaceSymbols;
exports.default = _default;
@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
const matchValueName = /[$]?[\w-]+/g;
const replaceValueSymbols = (value, replacements) => {
let matches;
while (matches = matchValueName.exec(value)) {
const replacement = replacements[matches[0]];
if (replacement) {
value = value.slice(0, matches.index) + replacement + value.slice(matchValueName.lastIndex);
matchValueName.lastIndex -= matches[0].length - replacement.length;
}
}
return value;
};
var _default = replaceValueSymbols;
exports.default = _default;
+86
View File
@@ -0,0 +1,86 @@
{
"name": "icss-utils",
"version": "4.1.1",
"description": "ICSS utils for postcss ast",
"main": "lib/index.js",
"engines": {
"node": ">= 6"
},
"files": [
"lib"
],
"scripts": {
"lint": "eslint . --ignore-path .gitignore",
"build": "babel --out-dir lib src",
"pretest": "npm run lint",
"test": "npm run test:only",
"test:only": "jest",
"prepublish": "yarn test && yarn run build"
},
"babel": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": 6
}
}
]
]
},
"eslintConfig": {
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module"
},
"env": {
"es6": true,
"jest": true
},
"extends": "eslint:recommended"
},
"lint-staged": {
"*.js": [
"prettier --write",
"eslint",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/css-modules/icss-utils.git"
},
"keywords": [
"css",
"modules",
"icss",
"postcss"
],
"author": "Glen Maddern",
"license": "ISC",
"bugs": {
"url": "https://github.com/css-modules/icss-utils/issues"
},
"homepage": "https://github.com/css-modules/icss-utils#readme",
"dependencies": {
"postcss": "^7.0.14"
},
"devDependencies": {
"@babel/cli": "^7.1.0",
"@babel/core": "^7.1.0",
"@babel/preset-env": "^7.1.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^24.1.0",
"eslint": "^5.14.1",
"husky": "^1.3.1",
"jest": "^24.1.0",
"lint-staged": "^8.1.4",
"prettier": "^1.16.4"
}
}
+296
View File
@@ -0,0 +1,296 @@
# 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.
## [2.6.0](https://github.com/broofa/mime/compare/v2.5.2...v2.6.0) (2021-11-02)
### Features
* mime-db@1.50.0 ([cef0cc4](https://github.com/broofa/mime/commit/cef0cc484ff6d05ff1e12b54ca3e8b856fbc14d8))
### [2.5.2](https://github.com/broofa/mime/compare/v2.5.0...v2.5.2) (2021-02-17)
### Bug Fixes
* update to mime-db@1.46.0, fixes [#253](https://github.com/broofa/mime/issues/253) ([f10e6aa](https://github.com/broofa/mime/commit/f10e6aa62e1356de7e2491d7fb4374c8dac65800))
## [2.5.0](https://github.com/broofa/mime/compare/v2.4.7...v2.5.0) (2021-01-16)
### Features
* improved CLI ([#244](https://github.com/broofa/mime/issues/244)) ([c8a8356](https://github.com/broofa/mime/commit/c8a8356e3b27f3ef46b64b89b428fdb547b14d5f))
### [2.4.7](https://github.com/broofa/mime/compare/v2.4.6...v2.4.7) (2020-12-16)
### Bug Fixes
* update to latest mime-db ([43b09ef](https://github.com/broofa/mime/commit/43b09eff0233eacc449af2b1f99a19ba9e104a44))
### [2.4.6](https://github.com/broofa/mime/compare/v2.4.5...v2.4.6) (2020-05-27)
### Bug Fixes
* add cli.js to package.json files ([#237](https://github.com/broofa/mime/issues/237)) ([6c070bc](https://github.com/broofa/mime/commit/6c070bc298fa12a48e2ed126fbb9de641a1e7ebc))
### [2.4.5](https://github.com/broofa/mime/compare/v2.4.4...v2.4.5) (2020-05-01)
### Bug Fixes
* fix [#236](https://github.com/broofa/mime/issues/236) ([7f4ecd0](https://github.com/broofa/mime/commit/7f4ecd0d850ed22c9e3bfda2c11fc74e4dde12a7))
* update to latest mime-db ([c5cb3f2](https://github.com/broofa/mime/commit/c5cb3f2ab8b07642a066efbde1142af1b90c927b))
### [2.4.4](https://github.com/broofa/mime/compare/v2.4.3...v2.4.4) (2019-06-07)
### [2.4.3](https://github.com/broofa/mime/compare/v2.4.2...v2.4.3) (2019-05-15)
### [2.4.2](https://github.com/broofa/mime/compare/v2.4.1...v2.4.2) (2019-04-07)
### Bug Fixes
* don't use arrow function introduced in 2.4.1 ([2e00b5c](https://github.com/broofa/mime/commit/2e00b5c))
### [2.4.1](https://github.com/broofa/mime/compare/v2.4.0...v2.4.1) (2019-04-03)
### Bug Fixes
* update MDN and mime-db types ([3e567a9](https://github.com/broofa/mime/commit/3e567a9))
# [2.4.0](https://github.com/broofa/mime/compare/v2.3.1...v2.4.0) (2018-11-26)
### Features
* Bind exported methods ([9d2a7b8](https://github.com/broofa/mime/commit/9d2a7b8))
* update to mime-db@1.37.0 ([49e6e41](https://github.com/broofa/mime/commit/49e6e41))
### [2.3.1](https://github.com/broofa/mime/compare/v2.3.0...v2.3.1) (2018-04-11)
### Bug Fixes
* fix [#198](https://github.com/broofa/mime/issues/198) ([25ca180](https://github.com/broofa/mime/commit/25ca180))
# [2.3.0](https://github.com/broofa/mime/compare/v2.2.2...v2.3.0) (2018-04-11)
### Bug Fixes
* fix [#192](https://github.com/broofa/mime/issues/192) ([5c35df6](https://github.com/broofa/mime/commit/5c35df6))
### Features
* add travis-ci testing ([d64160f](https://github.com/broofa/mime/commit/d64160f))
### [2.2.2](https://github.com/broofa/mime/compare/v2.2.1...v2.2.2) (2018-03-30)
### Bug Fixes
* update types files to mime-db@1.32.0 ([85aac16](https://github.com/broofa/mime/commit/85aac16))
### [2.2.1](https://github.com/broofa/mime/compare/v2.2.0...v2.2.1) (2018-03-30)
### Bug Fixes
* Retain type->extension mappings for non-default types. Fixes [#180](https://github.com/broofa/mime/issues/180) ([b5c83fb](https://github.com/broofa/mime/commit/b5c83fb))
# [2.2.0](https://github.com/broofa/mime/compare/v2.1.0...v2.2.0) (2018-01-04)
### Features
* Retain type->extension mappings for non-default types. Fixes [#180](https://github.com/broofa/mime/issues/180) ([10f82ac](https://github.com/broofa/mime/commit/10f82ac))
# [2.1.0](https://github.com/broofa/mime/compare/v2.0.5...v2.1.0) (2017-12-22)
### Features
* Upgrade to mime-db@1.32.0. Fixes [#185](https://github.com/broofa/mime/issues/185) ([3f775ba](https://github.com/broofa/mime/commit/3f775ba))
### [2.0.5](https://github.com/broofa/mime/compare/v2.0.1...v2.0.5) (2017-12-22)
### Bug Fixes
* ES5 support (back to node v0.4) ([f14ccb6](https://github.com/broofa/mime/commit/f14ccb6))
# Changelog
### v2.0.4 (24/11/2017)
- [**closed**] Switch to mime-score module for resolving extension contention issues. [#182](https://github.com/broofa/mime/issues/182)
- [**closed**] Update mime-db to 1.31.0 in v1.x branch [#181](https://github.com/broofa/mime/issues/181)
---
## v1.5.0 (22/11/2017)
- [**closed**] need ES5 version ready in npm package [#179](https://github.com/broofa/mime/issues/179)
- [**closed**] mime-db no trace of iWork - pages / numbers / etc. [#178](https://github.com/broofa/mime/issues/178)
- [**closed**] How it works in brownser ? [#176](https://github.com/broofa/mime/issues/176)
- [**closed**] Missing `./Mime` [#175](https://github.com/broofa/mime/issues/175)
- [**closed**] Vulnerable Regular Expression [#167](https://github.com/broofa/mime/issues/167)
---
### v2.0.3 (25/09/2017)
*No changelog for this release.*
---
### v1.4.1 (25/09/2017)
- [**closed**] Issue when bundling with webpack [#172](https://github.com/broofa/mime/issues/172)
---
### v2.0.2 (15/09/2017)
- [**V2**] fs.readFileSync is not a function [#165](https://github.com/broofa/mime/issues/165)
- [**closed**] The extension for video/quicktime should map to .mov, not .qt [#164](https://github.com/broofa/mime/issues/164)
- [**V2**] [v2 Feedback request] Mime class API [#163](https://github.com/broofa/mime/issues/163)
- [**V2**] [v2 Feedback request] Resolving conflicts over extensions [#162](https://github.com/broofa/mime/issues/162)
- [**V2**] Allow callers to load module with official, full, or no defined types. [#161](https://github.com/broofa/mime/issues/161)
- [**V2**] Use "facets" to resolve extension conflicts [#160](https://github.com/broofa/mime/issues/160)
- [**V2**] Remove fs and path dependencies [#152](https://github.com/broofa/mime/issues/152)
- [**V2**] Default content-type should not be application/octet-stream [#139](https://github.com/broofa/mime/issues/139)
- [**V2**] reset mime-types [#124](https://github.com/broofa/mime/issues/124)
- [**V2**] Extensionless paths should return null or false [#113](https://github.com/broofa/mime/issues/113)
---
### v2.0.1 (14/09/2017)
- [**closed**] Changelog for v2.0 does not mention breaking changes [#171](https://github.com/broofa/mime/issues/171)
- [**closed**] MIME breaking with 'class' declaration as it is without 'use strict mode' [#170](https://github.com/broofa/mime/issues/170)
---
## v2.0.0 (12/09/2017)
- [**closed**] woff and woff2 [#168](https://github.com/broofa/mime/issues/168)
---
## v1.4.0 (28/08/2017)
- [**closed**] support for ac3 voc files [#159](https://github.com/broofa/mime/issues/159)
- [**closed**] Help understanding change from application/xml to text/xml [#158](https://github.com/broofa/mime/issues/158)
- [**closed**] no longer able to override mimetype [#157](https://github.com/broofa/mime/issues/157)
- [**closed**] application/vnd.adobe.photoshop [#147](https://github.com/broofa/mime/issues/147)
- [**closed**] Directories should appear as something other than application/octet-stream [#135](https://github.com/broofa/mime/issues/135)
- [**closed**] requested features [#131](https://github.com/broofa/mime/issues/131)
- [**closed**] Make types.json loading optional? [#129](https://github.com/broofa/mime/issues/129)
- [**closed**] Cannot find module './types.json' [#120](https://github.com/broofa/mime/issues/120)
- [**V2**] .wav files show up as "audio/x-wav" instead of "audio/x-wave" [#118](https://github.com/broofa/mime/issues/118)
- [**closed**] Don't be a pain in the ass for node community [#108](https://github.com/broofa/mime/issues/108)
- [**closed**] don't make default_type global [#78](https://github.com/broofa/mime/issues/78)
- [**closed**] mime.extension() fails if the content-type is parameterized [#74](https://github.com/broofa/mime/issues/74)
---
### v1.3.6 (11/05/2017)
- [**closed**] .md should be text/markdown as of March 2016 [#154](https://github.com/broofa/mime/issues/154)
- [**closed**] Error while installing mime [#153](https://github.com/broofa/mime/issues/153)
- [**closed**] application/manifest+json [#149](https://github.com/broofa/mime/issues/149)
- [**closed**] Dynamic adaptive streaming over HTTP (DASH) file extension typo [#141](https://github.com/broofa/mime/issues/141)
- [**closed**] charsets image/png undefined [#140](https://github.com/broofa/mime/issues/140)
- [**closed**] Mime-db dependency out of date [#130](https://github.com/broofa/mime/issues/130)
- [**closed**] how to support plist [#126](https://github.com/broofa/mime/issues/126)
- [**closed**] how does .types file format look like? [#123](https://github.com/broofa/mime/issues/123)
- [**closed**] Feature: support for expanding MIME patterns [#121](https://github.com/broofa/mime/issues/121)
- [**closed**] DEBUG_MIME doesn't work [#117](https://github.com/broofa/mime/issues/117)
---
### v1.3.4 (06/02/2015)
*No changelog for this release.*
---
### v1.3.3 (06/02/2015)
*No changelog for this release.*
---
### v1.3.1 (05/02/2015)
- [**closed**] Consider adding support for Handlebars .hbs file ending [#111](https://github.com/broofa/mime/issues/111)
- [**closed**] Consider adding support for hjson. [#110](https://github.com/broofa/mime/issues/110)
- [**closed**] Add mime type for Opus audio files [#94](https://github.com/broofa/mime/issues/94)
- [**closed**] Consider making the `Requesting New Types` information more visible [#77](https://github.com/broofa/mime/issues/77)
---
## v1.3.0 (05/02/2015)
- [**closed**] Add common name? [#114](https://github.com/broofa/mime/issues/114)
- [**closed**] application/x-yaml [#104](https://github.com/broofa/mime/issues/104)
- [**closed**] Add mime type for WOFF file format 2.0 [#102](https://github.com/broofa/mime/issues/102)
- [**closed**] application/x-msi for .msi [#99](https://github.com/broofa/mime/issues/99)
- [**closed**] Add mimetype for gettext translation files [#98](https://github.com/broofa/mime/issues/98)
- [**closed**] collaborators [#88](https://github.com/broofa/mime/issues/88)
- [**closed**] getting errot in installation of mime module...any1 can help? [#87](https://github.com/broofa/mime/issues/87)
- [**closed**] should application/json's charset be utf8? [#86](https://github.com/broofa/mime/issues/86)
- [**closed**] Add "license" and "licenses" to package.json [#81](https://github.com/broofa/mime/issues/81)
- [**closed**] lookup with extension-less file on Windows returns wrong type [#68](https://github.com/broofa/mime/issues/68)
---
### v1.2.11 (15/08/2013)
- [**closed**] Update mime.types [#65](https://github.com/broofa/mime/issues/65)
- [**closed**] Publish a new version [#63](https://github.com/broofa/mime/issues/63)
- [**closed**] README should state upfront that "application/octet-stream" is default for unknown extension [#55](https://github.com/broofa/mime/issues/55)
- [**closed**] Suggested improvement to the charset API [#52](https://github.com/broofa/mime/issues/52)
---
### v1.2.10 (25/07/2013)
- [**closed**] Mime type for woff files should be application/font-woff and not application/x-font-woff [#62](https://github.com/broofa/mime/issues/62)
- [**closed**] node.types in conflict with mime.types [#51](https://github.com/broofa/mime/issues/51)
---
### v1.2.9 (17/01/2013)
- [**closed**] Please update "mime" NPM [#49](https://github.com/broofa/mime/issues/49)
- [**closed**] Please add semicolon [#46](https://github.com/broofa/mime/issues/46)
- [**closed**] parse full mime types [#43](https://github.com/broofa/mime/issues/43)
---
### v1.2.8 (10/01/2013)
- [**closed**] /js directory mime is application/javascript. Is it correct? [#47](https://github.com/broofa/mime/issues/47)
- [**closed**] Add mime types for lua code. [#45](https://github.com/broofa/mime/issues/45)
---
### v1.2.7 (19/10/2012)
- [**closed**] cannot install 1.2.7 via npm [#41](https://github.com/broofa/mime/issues/41)
- [**closed**] Transfer ownership to @broofa [#36](https://github.com/broofa/mime/issues/36)
- [**closed**] it's wrong to set charset to UTF-8 for text [#30](https://github.com/broofa/mime/issues/30)
- [**closed**] Allow multiple instances of MIME types container [#27](https://github.com/broofa/mime/issues/27)
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+97
View File
@@ -0,0 +1,97 @@
'use strict';
/**
* @param typeMap [Object] Map of MIME type -> Array[extensions]
* @param ...
*/
function Mime() {
this._types = Object.create(null);
this._extensions = Object.create(null);
for (let i = 0; i < arguments.length; i++) {
this.define(arguments[i]);
}
this.define = this.define.bind(this);
this.getType = this.getType.bind(this);
this.getExtension = this.getExtension.bind(this);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* If a type declares an extension that has already been defined, an error will
* be thrown. To suppress this error and force the extension to be associated
* with the new type, pass `force`=true. Alternatively, you may prefix the
* extension with "*" to map the type to extension, without mapping the
* extension to the type.
*
* e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
*
*
* @param map (Object) type definitions
* @param force (Boolean) if true, force overriding of existing definitions
*/
Mime.prototype.define = function(typeMap, force) {
for (let type in typeMap) {
let extensions = typeMap[type].map(function(t) {
return t.toLowerCase();
});
type = type.toLowerCase();
for (let i = 0; i < extensions.length; i++) {
const ext = extensions[i];
// '*' prefix = not the preferred type for this extension. So fixup the
// extension, and skip it.
if (ext[0] === '*') {
continue;
}
if (!force && (ext in this._types)) {
throw new Error(
'Attempt to change mapping for "' + ext +
'" extension from "' + this._types[ext] + '" to "' + type +
'". Pass `force=true` to allow this, otherwise remove "' + ext +
'" from the list of extensions for "' + type + '".'
);
}
this._types[ext] = type;
}
// Use first extension as default
if (force || !this._extensions[type]) {
const ext = extensions[0];
this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
}
}
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.getType = function(path) {
path = String(path);
let last = path.replace(/^.*[/\\]/, '').toLowerCase();
let ext = last.replace(/^.*\./, '').toLowerCase();
let hasPath = last.length < path.length;
let hasDot = ext.length < last.length - 1;
return (hasDot || !hasPath) && this._types[ext] || null;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.getExtension = function(type) {
type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
return type && this._extensions[type.toLowerCase()] || null;
};
module.exports = Mime;
+187
View File
@@ -0,0 +1,187 @@
<!--
-- This file is auto-generated from src/README_js.md. Changes should be made there.
-->
# Mime
A comprehensive, compact MIME type module.
[![Build Status](https://travis-ci.org/broofa/mime.svg?branch=master)](https://travis-ci.org/broofa/mime)
## Version 2 Notes
Version 2 is a breaking change from 1.x as the semver implies. Specifically:
* `lookup()` renamed to `getType()`
* `extension()` renamed to `getExtension()`
* `charset()` and `load()` methods have been removed
If you prefer the legacy version of this module please `npm install mime@^1`. Version 1 docs may be found [here](https://github.com/broofa/mime/tree/v1.4.0).
## Install
### NPM
```
npm install mime
```
### Browser
It is recommended that you use a bundler such as
[webpack](https://webpack.github.io/) or [browserify](http://browserify.org/) to
package your code. However, browser-ready versions are available via wzrd.in.
E.g. For the full version:
<script src="https://wzrd.in/standalone/mime@latest"></script>
<script>
mime.getType(...); // etc.
</script>
Or, for the `mime/lite` version:
<script src="https://wzrd.in/standalone/mime%2flite@latest"></script>
<script>
mimelite.getType(...); // (Note `mimelite` here)
</script>
## Quick Start
For the full version (800+ MIME types, 1,000+ extensions):
```javascript
const mime = require('mime');
mime.getType('txt'); // ⇨ 'text/plain'
mime.getExtension('text/plain'); // ⇨ 'txt'
```
See [Mime API](#mime-api) below for API details.
## Lite Version
There is also a "lite" version of this module that omits vendor-specific
(`*/vnd.*`) and experimental (`*/x-*`) types. It weighs in at ~2.5KB, compared
to 8KB for the full version. To load the lite version:
```javascript
const mime = require('mime/lite');
```
## Mime .vs. mime-types .vs. mime-db modules
For those of you wondering about the difference between these [popular] NPM modules,
here's a brief rundown ...
[`mime-db`](https://github.com/jshttp/mime-db) is "the source of
truth" for MIME type information. It is not an API. Rather, it is a canonical
dataset of mime type definitions pulled from IANA, Apache, NGINX, and custom mappings
submitted by the Node.js community.
[`mime-types`](https://github.com/jshttp/mime-types) is a thin
wrapper around mime-db that provides an API drop-in compatible(ish) with `mime @ < v1.3.6` API.
`mime` is, as of v2, a self-contained module bundled with a pre-optimized version
of the `mime-db` dataset. It provides a simplified API with the following characteristics:
* Intelligently resolved type conflicts (See [mime-score](https://github.com/broofa/mime-score) for details)
* Method naming consistent with industry best-practices
* Compact footprint. E.g. The minified+compressed sizes of the various modules:
Module | Size
--- | ---
`mime-db` | 18 KB
`mime-types` | same as mime-db
`mime` | 8 KB
`mime/lite` | 2 KB
## Mime API
Both `require('mime')` and `require('mime/lite')` return instances of the MIME
class, documented below.
Note: Inputs to this API are case-insensitive. Outputs (returned values) will
be lowercase.
### new Mime(typeMap, ... more maps)
Most users of this module will not need to create Mime instances directly.
However if you would like to create custom mappings, you may do so as follows
...
```javascript
// Require Mime class
const Mime = require('mime/Mime');
// Define mime type -> extensions map
const typeMap = {
'text/abc': ['abc', 'alpha', 'bet'],
'text/def': ['leppard']
};
// Create and use Mime instance
const myMime = new Mime(typeMap);
myMime.getType('abc'); // ⇨ 'text/abc'
myMime.getExtension('text/def'); // ⇨ 'leppard'
```
If more than one map argument is provided, each map is `define()`ed (see below), in order.
### mime.getType(pathOrExtension)
Get mime type for the given path or extension. E.g.
```javascript
mime.getType('js'); // ⇨ 'application/javascript'
mime.getType('json'); // ⇨ 'application/json'
mime.getType('txt'); // ⇨ 'text/plain'
mime.getType('dir/text.txt'); // ⇨ 'text/plain'
mime.getType('dir\\text.txt'); // ⇨ 'text/plain'
mime.getType('.text.txt'); // ⇨ 'text/plain'
mime.getType('.txt'); // ⇨ 'text/plain'
```
`null` is returned in cases where an extension is not detected or recognized
```javascript
mime.getType('foo/txt'); // ⇨ null
mime.getType('bogus_type'); // ⇨ null
```
### mime.getExtension(type)
Get extension for the given mime type. Charset options (often included in
Content-Type headers) are ignored.
```javascript
mime.getExtension('text/plain'); // ⇨ 'txt'
mime.getExtension('application/json'); // ⇨ 'json'
mime.getExtension('text/html; charset=utf8'); // ⇨ 'html'
```
### mime.define(typeMap[, force = false])
Define [more] type mappings.
`typeMap` is a map of type -> extensions, as documented in `new Mime`, above.
By default this method will throw an error if you try to map a type to an
extension that is already assigned to another type. Passing `true` for the
`force` argument will suppress this behavior (overriding any previous mapping).
```javascript
mime.define({'text/x-abc': ['abc', 'abcd']});
mime.getType('abcd'); // ⇨ 'text/x-abc'
mime.getExtension('text/x-abc') // ⇨ 'abc'
```
## Command Line
mime [path_or_extension]
E.g.
> mime scripts/jquery.js
application/javascript
----
Markdown generated from [src/README_js.md](src/README_js.md) by [![RunMD Logo](http://i.imgur.com/h0FVyzU.png)](https://github.com/broofa/runmd)
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env node
'use strict';
process.title = 'mime';
let mime = require('.');
let pkg = require('./package.json');
let args = process.argv.splice(2);
if (args.includes('--version') || args.includes('-v') || args.includes('--v')) {
console.log(pkg.version);
process.exit(0);
} else if (args.includes('--name') || args.includes('-n') || args.includes('--n')) {
console.log(pkg.name);
process.exit(0);
} else if (args.includes('--help') || args.includes('-h') || args.includes('--h')) {
console.log(pkg.name + ' - ' + pkg.description + '\n');
console.log(`Usage:
mime [flags] [path_or_extension]
Flags:
--help, -h Show this message
--version, -v Display the version
--name, -n Print the name of the program
Note: the command will exit after it executes if a command is specified
The path_or_extension is the path to the file or the extension of the file.
Examples:
mime --help
mime --version
mime --name
mime -v
mime src/log.js
mime new.py
mime foo.sh
`);
process.exit(0);
}
let file = args[0];
let type = mime.getType(file);
process.stdout.write(type + '\n');
+4
View File
@@ -0,0 +1,4 @@
'use strict';
let Mime = require('./Mime');
module.exports = new Mime(require('./types/standard'), require('./types/other'));
+4
View File
@@ -0,0 +1,4 @@
'use strict';
let Mime = require('./Mime');
module.exports = new Mime(require('./types/standard'));
+52
View File
@@ -0,0 +1,52 @@
{
"author": {
"name": "Robert Kieffer",
"url": "http://github.com/broofa",
"email": "robert@broofa.com"
},
"engines": {
"node": ">=4.0.0"
},
"bin": {
"mime": "cli.js"
},
"contributors": [],
"description": "A comprehensive library for mime-type mapping",
"license": "MIT",
"dependencies": {},
"devDependencies": {
"benchmark": "*",
"chalk": "4.1.2",
"eslint": "8.1.0",
"mime-db": "1.50.0",
"mime-score": "1.2.0",
"mime-types": "2.1.33",
"mocha": "9.1.3",
"runmd": "*",
"standard-version": "9.3.2"
},
"files": [
"index.js",
"lite.js",
"Mime.js",
"cli.js",
"/types"
],
"scripts": {
"prepare": "node src/build.js && runmd --output README.md src/README_js.md",
"release": "standard-version",
"benchmark": "node src/benchmark.js",
"md": "runmd --watch --output README.md src/README_js.md",
"test": "mocha src/test.js"
},
"keywords": [
"util",
"mime"
],
"name": "mime",
"repository": {
"url": "https://github.com/broofa/mime",
"type": "git"
},
"version": "2.6.0"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,75 @@
# Change Log
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.
<a name="0.5.0"></a>
# [0.5.0](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.5...v0.5.0) (2018-12-07)
### Features
* add crossOriginLoading option support ([#313](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/313)) ([ffb0d87](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/ffb0d87))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.4...v0.4.5) (2018-11-21)
### Bug Fixes
* **index:** allow requesting failed async css files ([#292](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/292)) ([2eb0af5](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/2eb0af5))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.3...v0.4.4) (2018-10-10)
### Bug Fixes
* **index:** assign empty `module.id` to prevent `contenthash` from changing unnecessarily ([#284](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/284)) ([d7946d0](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/d7946d0))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.2...v0.4.3) (2018-09-18)
### Bug Fixes
* **loader:** pass `emitFile` to the child compilation (`loaderContext.emitFile`) ([#177](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/177)) ([18c066e](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/18c066e))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.0...v0.4.2) (2018-08-21)
### Bug Fixes
* use correct order when multiple chunk groups are merged ([#246](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/246)) ([c3b363d](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/c3b363d))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v0.4.0...v0.4.1) (2018-06-29)
### Bug Fixes
* CSS ordering with multiple entry points ([#130](https://github.com/webpack-contrib/mini-css-extract-plugin/issues/130)) ([79373eb](https://github.com/webpack-contrib/mini-css-extract-plugin/commit/79373eb))
# Change Log
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.
x.x.x / <year>-<month>-<day>
==================
* Bug fix -
* Feature -
* Chore -
* Docs -
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,320 @@
<div align="center">
<!-- replace with accurate logo e.g from https://worldvectorlogo.com/ -->
<img width="200" height="200" src="https://cdn.worldvectorlogo.com/logos/javascript.svg">
<a href="https://webpack.js.org/">
<img width="200" height="200" vspace="" hspace="25" src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon-square-big.svg">
</a>
<h1>mini-css-extract-plugin</h1>
</div>
[![npm][npm]][npm-url]
[![deps][deps]][deps-url]
[![tests][tests]][tests-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS. It supports On-Demand-Loading of CSS and SourceMaps.
It builds on top of a new webpack v4 feature (module types) and requires webpack 4 to work.
Compared to the extract-text-webpack-plugin:
* Async loading
* No duplicate compilation (performance)
* Easier to use
* Specific to CSS
TODO:
* HMR support
<h2 align="center">Install</h2>
```bash
npm install --save-dev mini-css-extract-plugin
```
<h2 align="center">Usage</h2>
### Configuration
#### Minimal example
**webpack.config.js**
```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it use publicPath in webpackOptions.output
publicPath: '../'
}
},
"css-loader"
]
}
]
}
}
```
#### Advanced configuration example
This plugin should be used only on `production` builds without `style-loader` in the loaders chain, especially if you want to have HMR in `development`.
Here is an example to have both HMR in `development` and your styles extracted in a file for `production` builds.
(Loaders options left out for clarity, adapt accordingly to your needs.)
**webpack.config.js**
```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[hash].css',
chunkFilename: devMode ? '[id].css' : '[id].[hash].css',
})
],
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'sass-loader',
],
}
]
}
}
```
### Minimizing For Production
While webpack 5 is likely to come with a CSS minimizer built-in, with webpack 4 you need to bring your own. To minify the output, use a plugin like [optimize-css-assets-webpack-plugin](https://github.com/NMFR/optimize-css-assets-webpack-plugin). Setting `optimization.minimizer` overrides the defaults provided by webpack, so make sure to also specify a JS minimizer:
**webpack.config.js**
```js
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: true // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({})
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
```
### Features
#### Using preloaded or inlined CSS
The runtime code detects already added CSS via `<link>` or `<style>` tag.
This can be useful when injecting CSS on server-side for Server-Side-Rendering.
The `href` of the `<link>` tag has to match the URL that will be used for loading the CSS chunk.
The `data-href` attribute can be used for `<link>` and `<style>` too.
When inlining CSS `data-href` must be used.
#### Extracting all CSS in a single file
Similar to what [extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin) does, the CSS
can be extracted in one CSS file using `optimization.splitChunks.cacheGroups`.
**webpack.config.js**
```js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
```
#### Extracting CSS based on entry
You may also extract the CSS based on the webpack entry name. This is especially useful if you import routes dynamically
but want to keep your CSS bundled according to entry. This also prevents the CSS duplication issue one had with the
ExtractTextPlugin.
```javascript
const path = require('path');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
function recursiveIssuer(m) {
if (m.issuer) {
return recursiveIssuer(m.issuer);
} else if (m.name) {
return m.name;
} else {
return false;
}
}
module.exports = {
entry: {
foo: path.resolve(__dirname, 'src/foo'),
bar: path.resolve(__dirname, 'src/bar')
},
optimization: {
splitChunks: {
cacheGroups: {
fooStyles: {
name: 'foo',
test: (m,c,entry = 'foo') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
},
barStyles: {
name: 'bar',
test: (m,c,entry = 'bar') => m.constructor.name === 'CssModule' && recursiveIssuer(m) === entry,
chunks: 'all',
enforce: true
}
}
}
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
})
],
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
]
}
]
}
}
```
#### Long Term Caching
For long term caching use `filename: "[contenthash].css"`. Optionally add `[name]`.
### Media Query Plugin
If you'd like to extract the media queries from the extracted CSS (so mobile users don't need to load desktop or tablet specific CSS anymore) you should use one of the following plugins:
- [Media Query Plugin](https://github.com/SassNinja/media-query-plugin)
- [Media Query Splitting Plugin](https://github.com/mike-diamond/media-query-splitting-plugin)
<h2 align="center">Maintainers</h2>
<table>
<tbody>
<tr>
<td align="center">
<a href="https://github.com/sokra">
<img width="150" height="150" src="https://github.com/sokra.png?size=150">
</br>
Tobias Koppers
</a>
</td>
</tr>
<tbody>
</table>
## License
#### [MIT](./LICENSE)
[npm]: https://img.shields.io/npm/v/mini-css-extract-plugin.svg
[npm-url]: https://npmjs.com/package/mini-css-extract-plugin
[node]: https://img.shields.io/node/v/mini-css-extract-plugin.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/mini-css-extract-plugin.svg
[deps-url]: https://david-dm.org/webpack-contrib/mini-css-extract-plugin
[tests]: https://img.shields.io/circleci/project/github/webpack-contrib/mini-css-extract-plugin.svg
[tests-url]: https://circleci.com/gh/webpack-contrib/mini-css-extract-plugin
[cover]: https://codecov.io/gh/webpack-contrib/mini-css-extract-plugin/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/mini-css-extract-plugin
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
@@ -0,0 +1,3 @@
'use strict';
module.exports = require('./index').default;
@@ -0,0 +1,392 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _webpack = require('webpack');
var _webpack2 = _interopRequireDefault(_webpack);
var _webpackSources = require('webpack-sources');
var _webpackSources2 = _interopRequireDefault(_webpackSources);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const { ConcatSource, SourceMapSource, OriginalSource } = _webpackSources2.default;
const {
Template,
util: { createHash }
} = _webpack2.default;
const MODULE_TYPE = 'css/mini-extract';
const pluginName = 'mini-css-extract-plugin';
const REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/i;
const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i;
const REGEXP_NAME = /\[name\]/i;
class CssDependency extends _webpack2.default.Dependency {
constructor({ identifier, content, media, sourceMap }, context, identifierIndex) {
super();
this.identifier = identifier;
this.identifierIndex = identifierIndex;
this.content = content;
this.media = media;
this.sourceMap = sourceMap;
this.context = context;
}
getResourceIdentifier() {
return `css-module-${this.identifier}-${this.identifierIndex}`;
}
}
class CssDependencyTemplate {
apply() {}
}
class CssModule extends _webpack2.default.Module {
constructor(dependency) {
super(MODULE_TYPE, dependency.context);
this.id = '';
this._identifier = dependency.identifier;
this._identifierIndex = dependency.identifierIndex;
this.content = dependency.content;
this.media = dependency.media;
this.sourceMap = dependency.sourceMap;
}
// no source() so webpack doesn't do add stuff to the bundle
size() {
return this.content.length;
}
identifier() {
return `css ${this._identifier} ${this._identifierIndex}`;
}
readableIdentifier(requestShortener) {
return `css ${requestShortener.shorten(this._identifier)}${this._identifierIndex ? ` (${this._identifierIndex})` : ''}`;
}
nameForCondition() {
const resource = this._identifier.split('!').pop();
const idx = resource.indexOf('?');
if (idx >= 0) return resource.substring(0, idx);
return resource;
}
updateCacheModule(module) {
this.content = module.content;
this.media = module.media;
this.sourceMap = module.sourceMap;
}
needRebuild() {
return true;
}
build(options, compilation, resolver, fileSystem, callback) {
this.buildInfo = {};
this.buildMeta = {};
callback();
}
updateHash(hash) {
super.updateHash(hash);
hash.update(this.content);
hash.update(this.media || '');
hash.update(this.sourceMap ? JSON.stringify(this.sourceMap) : '');
}
}
class CssModuleFactory {
create({
dependencies: [dependency]
}, callback) {
callback(null, new CssModule(dependency));
}
}
class MiniCssExtractPlugin {
constructor(options) {
this.options = Object.assign({
filename: '[name].css'
}, options);
if (!this.options.chunkFilename) {
const { filename } = this.options;
const hasName = filename.includes('[name]');
const hasId = filename.includes('[id]');
const hasChunkHash = filename.includes('[chunkhash]');
// Anything changing depending on chunk is fine
if (hasChunkHash || hasName || hasId) {
this.options.chunkFilename = filename;
} else {
// Elsewise prefix '[id].' in front of the basename to make it changing
this.options.chunkFilename = filename.replace(/(^|\/)([^/]*(?:\?|$))/, '$1[id].$2');
}
}
}
apply(compiler) {
compiler.hooks.thisCompilation.tap(pluginName, compilation => {
compilation.hooks.normalModuleLoader.tap(pluginName, (lc, m) => {
const loaderContext = lc;
const module = m;
loaderContext[MODULE_TYPE] = content => {
if (!Array.isArray(content) && content != null) {
throw new Error(`Exported value was not extracted as an array: ${JSON.stringify(content)}`);
}
const identifierCountMap = new Map();
for (const line of content) {
const count = identifierCountMap.get(line.identifier) || 0;
module.addDependency(new CssDependency(line, m.context, count));
identifierCountMap.set(line.identifier, count + 1);
}
};
});
compilation.dependencyFactories.set(CssDependency, new CssModuleFactory());
compilation.dependencyTemplates.set(CssDependency, new CssDependencyTemplate());
compilation.mainTemplate.hooks.renderManifest.tap(pluginName, (result, { chunk }) => {
const renderedModules = Array.from(chunk.modulesIterable).filter(module => module.type === MODULE_TYPE);
if (renderedModules.length > 0) {
result.push({
render: () => this.renderContentAsset(compilation, chunk, renderedModules, compilation.runtimeTemplate.requestShortener),
filenameTemplate: this.options.filename,
pathOptions: {
chunk,
contentHashType: MODULE_TYPE
},
identifier: `${pluginName}.${chunk.id}`,
hash: chunk.contentHash[MODULE_TYPE]
});
}
});
compilation.chunkTemplate.hooks.renderManifest.tap(pluginName, (result, { chunk }) => {
const renderedModules = Array.from(chunk.modulesIterable).filter(module => module.type === MODULE_TYPE);
if (renderedModules.length > 0) {
result.push({
render: () => this.renderContentAsset(compilation, chunk, renderedModules, compilation.runtimeTemplate.requestShortener),
filenameTemplate: this.options.chunkFilename,
pathOptions: {
chunk,
contentHashType: MODULE_TYPE
},
identifier: `${pluginName}.${chunk.id}`,
hash: chunk.contentHash[MODULE_TYPE]
});
}
});
compilation.mainTemplate.hooks.hashForChunk.tap(pluginName, (hash, chunk) => {
const { chunkFilename } = this.options;
if (REGEXP_CHUNKHASH.test(chunkFilename)) {
hash.update(JSON.stringify(chunk.getChunkMaps(true).hash));
}
if (REGEXP_CONTENTHASH.test(chunkFilename)) {
hash.update(JSON.stringify(chunk.getChunkMaps(true).contentHash[MODULE_TYPE] || {}));
}
if (REGEXP_NAME.test(chunkFilename)) {
hash.update(JSON.stringify(chunk.getChunkMaps(true).name));
}
});
compilation.hooks.contentHash.tap(pluginName, chunk => {
const { outputOptions } = compilation;
const { hashFunction, hashDigest, hashDigestLength } = outputOptions;
const hash = createHash(hashFunction);
for (const m of chunk.modulesIterable) {
if (m.type === MODULE_TYPE) {
m.updateHash(hash);
}
}
const { contentHash } = chunk;
contentHash[MODULE_TYPE] = hash.digest(hashDigest).substring(0, hashDigestLength);
});
const { mainTemplate } = compilation;
mainTemplate.hooks.localVars.tap(pluginName, (source, chunk) => {
const chunkMap = this.getCssChunkObject(chunk);
if (Object.keys(chunkMap).length > 0) {
return Template.asString([source, '', '// object to store loaded CSS chunks', 'var installedCssChunks = {', Template.indent(chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(',\n')), '}']);
}
return source;
});
mainTemplate.hooks.requireEnsure.tap(pluginName, (source, chunk, hash) => {
const chunkMap = this.getCssChunkObject(chunk);
if (Object.keys(chunkMap).length > 0) {
const chunkMaps = chunk.getChunkMaps();
const { crossOriginLoading } = mainTemplate.outputOptions;
const linkHrefPath = mainTemplate.getAssetPath(JSON.stringify(this.options.chunkFilename), {
hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`,
hashWithLength: length => `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`,
chunk: {
id: '" + chunkId + "',
hash: `" + ${JSON.stringify(chunkMaps.hash)}[chunkId] + "`,
hashWithLength(length) {
const shortChunkHashMap = Object.create(null);
for (const chunkId of Object.keys(chunkMaps.hash)) {
if (typeof chunkMaps.hash[chunkId] === 'string') {
shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substring(0, length);
}
}
return `" + ${JSON.stringify(shortChunkHashMap)}[chunkId] + "`;
},
contentHash: {
[MODULE_TYPE]: `" + ${JSON.stringify(chunkMaps.contentHash[MODULE_TYPE])}[chunkId] + "`
},
contentHashWithLength: {
[MODULE_TYPE]: length => {
const shortContentHashMap = {};
const contentHash = chunkMaps.contentHash[MODULE_TYPE];
for (const chunkId of Object.keys(contentHash)) {
if (typeof contentHash[chunkId] === 'string') {
shortContentHashMap[chunkId] = contentHash[chunkId].substring(0, length);
}
}
return `" + ${JSON.stringify(shortContentHashMap)}[chunkId] + "`;
}
},
name: `" + (${JSON.stringify(chunkMaps.name)}[chunkId]||chunkId) + "`
},
contentHashType: MODULE_TYPE
});
return Template.asString([source, '', `// ${pluginName} CSS loading`, `var cssChunks = ${JSON.stringify(chunkMap)};`, 'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);', 'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {', Template.indent(['promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) {', Template.indent([`var href = ${linkHrefPath};`, `var fullhref = ${mainTemplate.requireFn}.p + href;`, 'var existingLinkTags = document.getElementsByTagName("link");', 'for(var i = 0; i < existingLinkTags.length; i++) {', Template.indent(['var tag = existingLinkTags[i];', 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");', 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve();']), '}', 'var existingStyleTags = document.getElementsByTagName("style");', 'for(var i = 0; i < existingStyleTags.length; i++) {', Template.indent(['var tag = existingStyleTags[i];', 'var dataHref = tag.getAttribute("data-href");', 'if(dataHref === href || dataHref === fullhref) return resolve();']), '}', 'var linkTag = document.createElement("link");', 'linkTag.rel = "stylesheet";', 'linkTag.type = "text/css";', 'linkTag.onload = resolve;', 'linkTag.onerror = function(event) {', Template.indent(['var request = event && event.target && event.target.src || fullhref;', 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");', 'err.request = request;', 'delete installedCssChunks[chunkId]', 'linkTag.parentNode.removeChild(linkTag)', 'reject(err);']), '};', 'linkTag.href = fullhref;', crossOriginLoading ? Template.asString([`if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {`, Template.indent(`linkTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};`), '}']) : '', 'var head = document.getElementsByTagName("head")[0];', 'head.appendChild(linkTag);']), '}).then(function() {', Template.indent(['installedCssChunks[chunkId] = 0;']), '}));']), '}']);
}
return source;
});
});
}
getCssChunkObject(mainChunk) {
const obj = {};
for (const chunk of mainChunk.getAllAsyncChunks()) {
for (const module of chunk.modulesIterable) {
if (module.type === MODULE_TYPE) {
obj[chunk.id] = 1;
break;
}
}
}
return obj;
}
renderContentAsset(compilation, chunk, modules, requestShortener) {
let usedModules;
const [chunkGroup] = chunk.groupsIterable;
if (typeof chunkGroup.getModuleIndex2 === 'function') {
// Store dependencies for modules
const moduleDependencies = new Map(modules.map(m => [m, new Set()]));
// Get ordered list of modules per chunk group
// This loop also gathers dependencies from the ordered lists
// Lists are in reverse order to allow to use Array.pop()
const modulesByChunkGroup = Array.from(chunk.groupsIterable, cg => {
const sortedModules = modules.map(m => {
return {
module: m,
index: cg.getModuleIndex2(m)
};
}).filter(item => item.index !== undefined).sort((a, b) => b.index - a.index).map(item => item.module);
for (let i = 0; i < sortedModules.length; i++) {
const set = moduleDependencies.get(sortedModules[i]);
for (let j = i + 1; j < sortedModules.length; j++) {
set.add(sortedModules[j]);
}
}
return sortedModules;
});
// set with already included modules in correct order
usedModules = new Set();
const unusedModulesFilter = m => !usedModules.has(m);
while (usedModules.size < modules.length) {
let success = false;
let bestMatch;
let bestMatchDeps;
// get first module where dependencies are fulfilled
for (const list of modulesByChunkGroup) {
// skip and remove already added modules
while (list.length > 0 && usedModules.has(list[list.length - 1])) list.pop();
// skip empty lists
if (list.length !== 0) {
const module = list[list.length - 1];
const deps = moduleDependencies.get(module);
// determine dependencies that are not yet included
const failedDeps = Array.from(deps).filter(unusedModulesFilter);
// store best match for fallback behavior
if (!bestMatchDeps || bestMatchDeps.length > failedDeps.length) {
bestMatch = list;
bestMatchDeps = failedDeps;
}
if (failedDeps.length === 0) {
// use this module and remove it from list
usedModules.add(list.pop());
success = true;
break;
}
}
}
if (!success) {
// no module found => there is a conflict
// use list with fewest failed deps
// and emit a warning
const fallbackModule = bestMatch.pop();
compilation.warnings.push(new Error(`chunk ${chunk.name || chunk.id} [mini-css-extract-plugin]\n` + 'Conflicting order between:\n' + ` * ${fallbackModule.readableIdentifier(requestShortener)}\n` + `${bestMatchDeps.map(m => ` * ${m.readableIdentifier(requestShortener)}`).join('\n')}`));
usedModules.add(fallbackModule);
}
}
} else {
// fallback for older webpack versions
// (to avoid a breaking change)
// TODO remove this in next mayor version
// and increase minimum webpack version to 4.12.0
modules.sort((a, b) => a.index2 - b.index2);
usedModules = modules;
}
const source = new ConcatSource();
const externalsSource = new ConcatSource();
for (const m of usedModules) {
if (/^@import url/.test(m.content)) {
// HACK for IE
// http://stackoverflow.com/a/14676665/1458162
let { content } = m;
if (m.media) {
// insert media into the @import
// this is rar
// TODO improve this and parse the CSS to support multiple medias
content = content.replace(/;|\s*$/, m.media);
}
externalsSource.add(content);
externalsSource.add('\n');
} else {
if (m.media) {
source.add(`@media ${m.media} {\n`);
}
if (m.sourceMap) {
source.add(new SourceMapSource(m.content, m.readableIdentifier(requestShortener), m.sourceMap));
} else {
source.add(new OriginalSource(m.content, m.readableIdentifier(requestShortener)));
}
source.add('\n');
if (m.media) {
source.add('}\n');
}
}
}
return new ConcatSource(externalsSource, source);
}
}
MiniCssExtractPlugin.loader = require.resolve('./loader');
exports.default = MiniCssExtractPlugin;
@@ -0,0 +1,152 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pitch = pitch;
exports.default = function () {};
var _module = require('module');
var _module2 = _interopRequireDefault(_module);
var _loaderUtils = require('loader-utils');
var _loaderUtils2 = _interopRequireDefault(_loaderUtils);
var _NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
var _NodeTemplatePlugin2 = _interopRequireDefault(_NodeTemplatePlugin);
var _NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
var _NodeTargetPlugin2 = _interopRequireDefault(_NodeTargetPlugin);
var _LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
var _LibraryTemplatePlugin2 = _interopRequireDefault(_LibraryTemplatePlugin);
var _SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
var _SingleEntryPlugin2 = _interopRequireDefault(_SingleEntryPlugin);
var _LimitChunkCountPlugin = require('webpack/lib/optimize/LimitChunkCountPlugin');
var _LimitChunkCountPlugin2 = _interopRequireDefault(_LimitChunkCountPlugin);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const MODULE_TYPE = 'css/mini-extract';
const pluginName = 'mini-css-extract-plugin';
const exec = (loaderContext, code, filename) => {
const module = new _module2.default(filename, loaderContext);
module.paths = _module2.default._nodeModulePaths(loaderContext.context); // eslint-disable-line no-underscore-dangle
module.filename = filename;
module._compile(code, filename); // eslint-disable-line no-underscore-dangle
return module.exports;
};
const findModuleById = (modules, id) => {
for (const module of modules) {
if (module.id === id) {
return module;
}
}
return null;
};
function pitch(request) {
const query = _loaderUtils2.default.getOptions(this) || {};
const loaders = this.loaders.slice(this.loaderIndex + 1);
this.addDependency(this.resourcePath);
const childFilename = '*'; // eslint-disable-line no-path-concat
const publicPath = typeof query.publicPath === 'string' ? query.publicPath : this._compilation.outputOptions.publicPath;
const outputOptions = {
filename: childFilename,
publicPath
};
const childCompiler = this._compilation.createChildCompiler(`${pluginName} ${request}`, outputOptions);
new _NodeTemplatePlugin2.default(outputOptions).apply(childCompiler);
new _LibraryTemplatePlugin2.default(null, 'commonjs2').apply(childCompiler);
new _NodeTargetPlugin2.default().apply(childCompiler);
new _SingleEntryPlugin2.default(this.context, `!!${request}`, pluginName).apply(childCompiler);
new _LimitChunkCountPlugin2.default({ maxChunks: 1 }).apply(childCompiler);
// We set loaderContext[MODULE_TYPE] = false to indicate we already in
// a child compiler so we don't spawn another child compilers from there.
childCompiler.hooks.thisCompilation.tap(`${pluginName} loader`, compilation => {
compilation.hooks.normalModuleLoader.tap(`${pluginName} loader`, (loaderContext, module) => {
loaderContext.emitFile = this.emitFile;
loaderContext[MODULE_TYPE] = false; // eslint-disable-line no-param-reassign
if (module.request === request) {
// eslint-disable-next-line no-param-reassign
module.loaders = loaders.map(loader => {
return {
loader: loader.path,
options: loader.options,
ident: loader.ident
};
});
}
});
});
let source;
childCompiler.hooks.afterCompile.tap(pluginName, compilation => {
source = compilation.assets[childFilename] && compilation.assets[childFilename].source();
// Remove all chunk assets
compilation.chunks.forEach(chunk => {
chunk.files.forEach(file => {
delete compilation.assets[file]; // eslint-disable-line no-param-reassign
});
});
});
const callback = this.async();
childCompiler.runAsChild((err, entries, compilation) => {
if (err) return callback(err);
if (compilation.errors.length > 0) {
return callback(compilation.errors[0]);
}
compilation.fileDependencies.forEach(dep => {
this.addDependency(dep);
}, this);
compilation.contextDependencies.forEach(dep => {
this.addContextDependency(dep);
}, this);
if (!source) {
return callback(new Error("Didn't get a result from child compiler"));
}
let text;
let locals;
try {
text = exec(this, source, request);
locals = text && text.locals;
if (!Array.isArray(text)) {
text = [[null, text]];
} else {
text = text.map(line => {
const module = findModuleById(compilation.modules, line[0]);
return {
identifier: module.identifier(),
content: line[1],
media: line[2],
sourceMap: line[3]
};
});
}
this[MODULE_TYPE](text);
} catch (e) {
return callback(e);
}
let resultSource = `// extracted by ${pluginName}`;
if (locals && typeof resultSource !== 'undefined') {
resultSource += `\nmodule.exports = ${JSON.stringify(locals)};`;
}
return callback(null, resultSource);
});
}
@@ -0,0 +1,134 @@
# Change Log
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.
<a name="1.0.0"></a>
# [1.0.0](https://github.com/webpack-contrib/schema-utils/compare/v0.4.7...v1.0.0) (2018-08-07)
### Features
* **src:** add support for custom error messages ([#33](https://github.com/webpack-contrib/schema-utils/issues/33)) ([1cbe4ef](https://github.com/webpack-contrib/schema-utils/commit/1cbe4ef))
<a name="0.4.7"></a>
## [0.4.7](https://github.com/webpack-contrib/schema-utils/compare/v0.4.6...v0.4.7) (2018-08-07)
### Bug Fixes
* **src:** `node >= v4.0.0` support ([#32](https://github.com/webpack-contrib/schema-utils/issues/32)) ([cb13dd4](https://github.com/webpack-contrib/schema-utils/commit/cb13dd4))
<a name="0.4.6"></a>
## [0.4.6](https://github.com/webpack-contrib/schema-utils/compare/v0.4.5...v0.4.6) (2018-08-06)
### Bug Fixes
* **package:** remove lockfile ([#28](https://github.com/webpack-contrib/schema-utils/issues/28)) ([69f1a81](https://github.com/webpack-contrib/schema-utils/commit/69f1a81))
* **package:** remove unnecessary `webpack` dependency ([#26](https://github.com/webpack-contrib/schema-utils/issues/26)) ([532eaa5](https://github.com/webpack-contrib/schema-utils/commit/532eaa5))
<a name="0.4.5"></a>
## [0.4.5](https://github.com/webpack-contrib/schema-utils/compare/v0.4.4...v0.4.5) (2018-02-13)
### Bug Fixes
* **CHANGELOG:** update broken links ([4483b9f](https://github.com/webpack-contrib/schema-utils/commit/4483b9f))
* **package:** update broken links ([f2494ba](https://github.com/webpack-contrib/schema-utils/commit/f2494ba))
<a name="0.4.4"></a>
## [0.4.4](https://github.com/webpack-contrib/schema-utils/compare/v0.4.3...v0.4.4) (2018-02-13)
### Bug Fixes
* **package:** update `dependencies` ([#22](https://github.com/webpack-contrib/schema-utils/issues/22)) ([3aecac6](https://github.com/webpack-contrib/schema-utils/commit/3aecac6))
<a name="0.4.3"></a>
## [0.4.3](https://github.com/webpack-contrib/schema-utils/compare/v0.4.2...v0.4.3) (2017-12-14)
### Bug Fixes
* **validateOptions:** throw `err` instead of `process.exit(1)` ([#17](https://github.com/webpack-contrib/schema-utils/issues/17)) ([c595eda](https://github.com/webpack-contrib/schema-utils/commit/c595eda))
* **ValidationError:** never return `this` in the ctor ([#16](https://github.com/webpack-contrib/schema-utils/issues/16)) ([c723791](https://github.com/webpack-contrib/schema-utils/commit/c723791))
<a name="0.4.2"></a>
## [0.4.2](https://github.com/webpack-contrib/schema-utils/compare/v0.4.1...v0.4.2) (2017-11-09)
### Bug Fixes
* **validateOptions:** catch `ValidationError` and handle it internally ([#15](https://github.com/webpack-contrib/schema-utils/issues/15)) ([9c5ef5e](https://github.com/webpack-contrib/schema-utils/commit/9c5ef5e))
<a name="0.4.1"></a>
## [0.4.1](https://github.com/webpack-contrib/schema-utils/compare/v0.4.0...v0.4.1) (2017-11-03)
### Bug Fixes
* **ValidationError:** use `Error.captureStackTrace` for `err.stack` handling ([#14](https://github.com/webpack-contrib/schema-utils/issues/14)) ([a6fb974](https://github.com/webpack-contrib/schema-utils/commit/a6fb974))
<a name="0.4.0"></a>
# [0.4.0](https://github.com/webpack-contrib/schema-utils/compare/v0.3.0...v0.4.0) (2017-10-28)
### Features
* add support for `typeof`, `instanceof` (`{Function\|RegExp}`) ([#10](https://github.com/webpack-contrib/schema-utils/issues/10)) ([9f01816](https://github.com/webpack-contrib/schema-utils/commit/9f01816))
<a name="0.3.0"></a>
# [0.3.0](https://github.com/webpack-contrib/schema-utils/compare/v0.2.1...v0.3.0) (2017-04-29)
### Features
* add ValidationError ([#8](https://github.com/webpack-contrib/schema-utils/issues/8)) ([d48f0fb](https://github.com/webpack-contrib/schema-utils/commit/d48f0fb))
<a name="0.2.1"></a>
## [0.2.1](https://github.com/webpack-contrib/schema-utils/compare/v0.2.0...v0.2.1) (2017-03-13)
### Bug Fixes
* Include .babelrc to `files` ([28f0363](https://github.com/webpack-contrib/schema-utils/commit/28f0363))
* Include source to `files` ([43b0f2f](https://github.com/webpack-contrib/schema-utils/commit/43b0f2f))
<a name="0.2.0"></a>
# [0.2.0](https://github.com/webpack-contrib/schema-utils/compare/v0.1.0...v0.2.0) (2017-03-12)
<a name="0.1.0"></a>
# 0.1.0 (2017-03-07)
### Features
* **validations:** add validateOptions module ([ae9b47b](https://github.com/webpack-contrib/schema-utils/commit/ae9b47b))
# Change Log
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.
@@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,149 @@
[![npm][npm]][npm-url]
[![node][node]][node-url]
[![deps][deps]][deps-url]
[![test][test]][test-url]
[![coverage][cover]][cover-url]
[![chat][chat]][chat-url]
<div align="center">
<a href="http://json-schema.org">
<img width="160" height="160"
src="https://raw.githubusercontent.com/webpack-contrib/schema-utils/master/docs/logo.png">
</a>
<a href="https://github.com/webpack/webpack">
<img width="200" height="200"
src="https://webpack.js.org/assets/icon-square-big.svg">
</a>
<h1>Schema Utils</h1>
</div>
<h2 align="center">Install</h2>
```bash
npm i schema-utils
```
<h2 align="center">Usage</h2>
### `validateOptions`
**`schema.json`**
```js
{
"type": "object",
"properties": {
// Options...
},
"additionalProperties": false
}
```
#### Error Messages (Custom)
**`schema.json`**
```js
{
"type": "object",
"properties": {
"option": {
"type": [ "boolean" ]
}
},
// Overrides the default err.message for option
"errorMessage": {
"option": "should be {Boolean} (https:/github.com/org/repo#anchor)"
}
"additionalProperties": false
}
```
```js
import schema from 'path/to/schema.json'
import validateOptions from 'schema-utils'
validateOptions(schema, options, 'Loader/Plugin Name')
```
<h2 align="center">Examples</h2>
**schema.json**
```json
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"test": {
"anyOf": [
{ "type": "array" },
{ "type": "string" },
{ "instanceof": "RegExp" }
]
},
"transform": {
"instanceof": "Function"
},
"sourceMap": {
"type": "boolean"
}
},
"additionalProperties": false
}
```
### `Loader`
```js
import { getOptions } from 'loader-utils'
import validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
function loader (src, map) {
const options = getOptions(this) || {}
validateOptions(schema, options, 'Loader Name')
// Code...
}
```
### `Plugin`
```js
import validateOptions from 'schema-utils'
import schema from 'path/to/schema.json'
class Plugin {
constructor (options) {
validateOptions(schema, options, 'Plugin Name')
this.options = options
}
apply (compiler) {
// Code...
}
}
```
[npm]: https://img.shields.io/npm/v/schema-utils.svg
[npm-url]: https://npmjs.com/package/schema-utils
[node]: https://img.shields.io/node/v/schema-utils.svg
[node-url]: https://nodejs.org
[deps]: https://david-dm.org/webpack-contrib/schema-utils.svg
[deps-url]: https://david-dm.org/webpack-contrib/schema-utils
[test]: http://img.shields.io/travis/webpack-contrib/schema-utils.svg
[test-url]: https://travis-ci.org/webpack-contrib/schema-utils
[cover]: https://codecov.io/gh/webpack-contrib/schema-utils/branch/master/graph/badge.svg
[cover-url]: https://codecov.io/gh/webpack-contrib/schema-utils
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
[chat-url]: https://gitter.im/webpack/webpack
@@ -0,0 +1,41 @@
{
"name": "schema-utils",
"version": "1.0.0",
"description": "webpack Validation Utils",
"main": "src/index.js",
"files": [
"src"
],
"engines": {
"node": ">= 4"
},
"scripts": {
"lint": "eslint --cache src test",
"test": "jest --env node --verbose --coverage",
"clean": "del-cli coverage",
"commits": "commitlint --from $(git rev-list --tags --max-count=1)",
"release": "npm run commits && standard-version"
},
"dependencies": {
"ajv": "^6.1.0",
"ajv-errors": "^1.0.0",
"ajv-keywords": "^3.1.0"
},
"devDependencies": {
"@commitlint/cli": "^7.0.0",
"@commitlint/config-conventional": "^7.0.0",
"@webpack-contrib/eslint-config-webpack": "^2.0.0",
"del-cli": "^1.0.0",
"eslint": "^5.0.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-prettier": "^2.0.0",
"jest": "^21.0.0",
"prettier": "^1.0.0",
"standard-version": "^4.0.0"
},
"author": "webpack Contrib (https://github.com/webpack-contrib)",
"bugs": "https://github.com/webpack-contrib/schema-utils/issues",
"homepage": "https://github.com/webpack-contrib/schema-utils",
"repository": "https://github.com/webpack-contrib/schema-utils",
"license": "MIT"
}
@@ -0,0 +1,30 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
class ValidationError extends Error {
constructor(errors, name) {
super();
this.name = 'ValidationError';
this.message = `${name || ''} Invalid Options\n\n`;
this.errors = errors.map((err) => {
err.dataPath = err.dataPath.replace(/\//g, '.');
return err;
});
this.errors.forEach((err) => {
this.message += `options${err.dataPath} ${err.message}\n`;
});
Error.captureStackTrace(this, this.constructor);
}
}
module.exports = ValidationError;
@@ -0,0 +1,9 @@
/* eslint-disable
strict
*/
'use strict';
const validateOptions = require('./validateOptions');
module.exports = validateOptions;
@@ -0,0 +1,38 @@
/* eslint-disable
strict,
no-param-reassign
*/
'use strict';
const fs = require('fs');
const path = require('path');
const Ajv = require('ajv');
const errors = require('ajv-errors');
const keywords = require('ajv-keywords');
const ValidationError = require('./ValidationError');
const ajv = new Ajv({
allErrors: true,
jsonPointers: true,
});
errors(ajv);
keywords(ajv, ['instanceof', 'typeof']);
const validateOptions = (schema, options, name) => {
if (typeof schema === 'string') {
schema = fs.readFileSync(path.resolve(schema), 'utf8');
schema = JSON.parse(schema);
}
if (!ajv.validate(schema, options)) {
throw new ValidationError(ajv.errors, name);
}
return true;
};
module.exports = validateOptions;
@@ -0,0 +1,91 @@
{
"name": "mini-css-extract-plugin",
"version": "0.5.0",
"description": "extracts CSS into separate files",
"license": "MIT",
"repository": "webpack-contrib/mini-css-extract-plugin",
"author": "Tobias Koppers @sokra",
"homepage": "https://github.com/webpack-contrib/mini-css-extract-plugin",
"bugs": "https://github.com/webpack-contrib/mini-css-extract-plugin/issues",
"bin": "",
"main": "dist/cjs.js",
"engines": {
"node": ">= 6.9.0 <7.0.0 || >= 8.9.0"
},
"scripts": {
"start": "npm run build -- -w",
"build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files",
"clean": "del-cli dist",
"commitlint": "commitlint",
"commitmsg": "commitlint -e $GIT_PARAMS",
"lint": "eslint --cache src test",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"lint-staged": "lint-staged",
"prebuild": "npm run clean",
"prepublish": "npm run build",
"release": "standard-version",
"release:ci": "conventional-github-releaser -p angular",
"release:validate": "commitlint --from=$(git describe --tags --abbrev=0) --to=$(git rev-parse HEAD)",
"security": "nsp check",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage",
"test:manual": "webpack-dev-server test/manual/src/index.js --open --config test/manual/webpack.config.js",
"ci:lint": "npm run lint && npm run security",
"ci:test": "npm run test -- --runInBand",
"ci:coverage": "npm run test:coverage -- --runInBand",
"defaults": "webpack-defaults"
},
"files": [
"dist"
],
"peerDependencies": {
"webpack": "^4.4.0"
},
"dependencies": {
"schema-utils": "^1.0.0",
"loader-utils": "^1.1.0",
"webpack-sources": "^1.1.0"
},
"devDependencies": {
"@commitlint/cli": "^6.1.3",
"@commitlint/config-conventional": "^6.1.3",
"@webpack-contrib/eslint-config-webpack": "^2.0.4",
"babel-cli": "^6.26.0",
"babel-jest": "^22.2.2",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.6.1",
"conventional-github-releaser": "^2.0.2",
"cross-env": "^5.1.3",
"css-loader": "^0.28.10",
"del": "^3.0.0",
"del-cli": "^1.1.0",
"eslint": "^4.17.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-prettier": "^2.6.0",
"file-loader": "^1.1.11",
"husky": "^0.14.3",
"jest": "^22.2.2",
"lint-staged": "^6.1.0",
"memory-fs": "^0.4.1",
"nsp": "^3.1.0",
"pre-commit": "^1.2.2",
"prettier": "^1.11.1",
"standard-version": "^4.3.0",
"webpack": "^4.14.0",
"webpack-cli": "^2.0.13",
"webpack-defaults": "^2.3.0",
"webpack-dev-server": "^3.1.1"
},
"keywords": [
"webpack"
],
"pre-commit": "lint-staged",
"lint-staged": {
"*.js": [
"eslint --fix",
"git add"
]
}
}
+15
View File
@@ -0,0 +1,15 @@
ISC License
Copyright (c) 2021 Alexey Raspopov, Kostiantyn Denysov, Anton Verinov
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+23
View File
@@ -0,0 +1,23 @@
# picocolors
npm install picocolors
A tinier and faster alternative to [nanocolors](https://github.com/ai/nanocolors). Andrey, are you even trying?
```javascript
import pc from "picocolors";
console.log(pc.green(`How are ${pc.italic(`you`)} doing?`));
```
- Up to [2x faster and 2x smaller](#benchmarks) than alternatives
- 3x faster and 10x smaller than `chalk`
- [TypeScript](https://www.typescriptlang.org/) support
- [`NO_COLOR`](https://no-color.org/) friendly
- Node.js v6+ & browsers support
- The same API, but faster, much faster
- No `String.prototype` modifications (anyone still doing it?)
- No dependencies and the smallest `node_modules` footprint
## Docs
Read **[full docs](https://github.com/alexeyraspopov/picocolors#readme)** on GitHub.
+25
View File
@@ -0,0 +1,25 @@
{
"name": "picocolors",
"version": "0.2.1",
"main": "./picocolors.js",
"types": "./picocolors.d.ts",
"browser": {
"./picocolors.js": "./picocolors.browser.js"
},
"sideEffects": false,
"description": "The tiniest and the fastest coloring library ever",
"files": [
"picocolors.*",
"types.ts"
],
"keywords": [
"terminal",
"colors",
"formatting",
"cli",
"console"
],
"author": "Alexey Raspopov",
"repository": "alexeyraspopov/picocolors",
"license": "ISC"
}
@@ -0,0 +1,4 @@
var x=String;
var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x}};
module.exports=create();
module.exports.createColors = create;
@@ -0,0 +1,5 @@
import { Colors } from "./types"
declare const picocolors: Colors & { createColors: (enabled: boolean) => Colors }
export = picocolors
@@ -0,0 +1,60 @@
let tty = require("tty")
let isColorSupported =
!("NO_COLOR" in process.env || process.argv.includes("--no-color")) &&
("FORCE_COLOR" in process.env ||
process.argv.includes("--color") ||
process.platform === "win32" ||
(tty.isatty(1) && process.env.TERM !== "dumb") ||
"CI" in process.env)
function formatter(open, close, replace = open) {
return (input) => {
let string = "" + input
let index = string.indexOf(close, open.length)
return !~index
? open + string + close
: open + replaceClose(string, close, replace, index) + close
}
}
function replaceClose(string, close, replace, index) {
let start = string.substring(0, index) + replace
let end = string.substring(index + close.length)
let nextIndex = end.indexOf(close)
return !~nextIndex ? start + end : start + replaceClose(end, close, replace, nextIndex)
}
function createColors(enabled = isColorSupported) {
return {
isColorSupported: enabled,
reset: enabled ? (s) => `\x1b[0m${s}\x1b[0m` : String,
bold: enabled ? formatter("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m") : String,
dim: enabled ? formatter("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m") : String,
italic: enabled ? formatter("\x1b[3m", "\x1b[23m") : String,
underline: enabled ? formatter("\x1b[4m", "\x1b[24m") : String,
inverse: enabled ? formatter("\x1b[7m", "\x1b[27m") : String,
hidden: enabled ? formatter("\x1b[8m", "\x1b[28m") : String,
strikethrough: enabled ? formatter("\x1b[9m", "\x1b[29m") : String,
black: enabled ? formatter("\x1b[30m", "\x1b[39m") : String,
red: enabled ? formatter("\x1b[31m", "\x1b[39m") : String,
green: enabled ? formatter("\x1b[32m", "\x1b[39m") : String,
yellow: enabled ? formatter("\x1b[33m", "\x1b[39m") : String,
blue: enabled ? formatter("\x1b[34m", "\x1b[39m") : String,
magenta: enabled ? formatter("\x1b[35m", "\x1b[39m") : String,
cyan: enabled ? formatter("\x1b[36m", "\x1b[39m") : String,
white: enabled ? formatter("\x1b[37m", "\x1b[39m") : String,
gray: enabled ? formatter("\x1b[90m", "\x1b[39m") : String,
bgBlack: enabled ? formatter("\x1b[40m", "\x1b[49m") : String,
bgRed: enabled ? formatter("\x1b[41m", "\x1b[49m") : String,
bgGreen: enabled ? formatter("\x1b[42m", "\x1b[49m") : String,
bgYellow: enabled ? formatter("\x1b[43m", "\x1b[49m") : String,
bgBlue: enabled ? formatter("\x1b[44m", "\x1b[49m") : String,
bgMagenta: enabled ? formatter("\x1b[45m", "\x1b[49m") : String,
bgCyan: enabled ? formatter("\x1b[46m", "\x1b[49m") : String,
bgWhite: enabled ? formatter("\x1b[47m", "\x1b[49m") : String,
}
}
module.exports = createColors()
module.exports.createColors = createColors
+30
View File
@@ -0,0 +1,30 @@
export type Formatter = (input: string | number | null | undefined) => string
export interface Colors {
isColorSupported: boolean
reset: Formatter
bold: Formatter
dim: Formatter
italic: Formatter
underline: Formatter
inverse: Formatter
hidden: Formatter
strikethrough: Formatter
black: Formatter
red: Formatter
green: Formatter
yellow: Formatter
blue: Formatter
magenta: Formatter
cyan: Formatter
white: Formatter
gray: Formatter
bgBlack: Formatter
bgRed: Formatter
bgGreen: Formatter
bgYellow: Formatter
bgBlue: Formatter
bgMagenta: Formatter
bgCyan: Formatter
bgWhite: Formatter
}
@@ -0,0 +1,5 @@
Copyright 2015 Glen Maddern
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,79 @@
# CSS Modules: Extract Imports
[![Build Status](https://travis-ci.org/css-modules/postcss-modules-extract-imports.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-extract-imports)
Transforms:
```css
:local(.continueButton) {
composes: button from "library/button.css";
color: green;
}
```
into:
```css
:import("library/button.css") {
button: __tmp_487387465fczSDGHSABb;
}
:local(.continueButton) {
composes: __tmp_487387465fczSDGHSABb;
color: green;
}
```
## Specification
- Only a certain whitelist of properties are inspected. Currently, that whitelist is `['composes']` alone.
- An extend-import has the following format:
```
composes: className [... className] from "path/to/file.css";
```
## Options
- `failOnWrongOrder` `bool` generates exception for unpredictable imports order.
```css
.aa {
composes: b from './b.css';
composes: c from './c.css';
}
.bb {
/* "b.css" should be before "c.css" in this case */
composes: c from './c.css';
composes: b from './b.css';
}
```
## Building
```
npm install
npm test
```
[![Build Status](https://travis-ci.org/css-modules/postcss-modules-extract-imports.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-extract-imports)
* Lines: [![Coverage Status](https://coveralls.io/repos/css-modules/postcss-modules-extract-imports/badge.svg?branch=master)](https://coveralls.io/r/css-modules/postcss-modules-extract-imports?branch=master)
* Statements: [![codecov.io](http://codecov.io/github/css-modules/postcss-modules-extract-imports/coverage.svg?branch=master)](http://codecov.io/github/css-modules/postcss-modules-extract-imports?branch=master)
## Development
- `npm watch` will watch `src` for changes and rebuild
- `npm autotest` will watch `src` and `test` for changes and retest
## License
ISC
## With thanks
- Mark Dalgleish
- Tobias Koppers
- Guy Bedford
---
Glen Maddern, 2015.
@@ -0,0 +1,49 @@
{
"name": "postcss-modules-extract-imports",
"version": "2.0.0",
"description": "A CSS Modules transform to extract local aliases for inline imports",
"main": "src/index.js",
"engines": {
"node": ">= 6"
},
"files": [
"src"
],
"scripts": {
"test": "jest --coverage",
"precommit": "lint-staged",
"prepublish": "yarn run test"
},
"lint-staged": {
"*.js": [
"prettier --single-quote --no-semi --write",
"git add"
]
},
"repository": {
"type": "git",
"url": "https://github.com/css-modules/postcss-modules-extract-imports.git"
},
"keywords": [
"css-modules",
"postcss",
"plugin"
],
"author": "Glen Maddern",
"license": "ISC",
"bugs": {
"url": "https://github.com/css-modules/postcss-modules-extract-imports/issues"
},
"homepage": "https://github.com/css-modules/postcss-modules-extract-imports",
"dependencies": {
"postcss": "^7.0.5"
},
"devDependencies": {
"codecov.io": "^0.1.2",
"coveralls": "^2.11.2",
"husky": "^0.13.3",
"jest": "^20.0.3",
"lint-staged": "^3.4.2",
"prettier": "^1.3.1"
}
}
@@ -0,0 +1,180 @@
const postcss = require('postcss')
const topologicalSort = require('./topologicalSort')
const declWhitelist = ['composes']
const declFilter = new RegExp(`^(${declWhitelist.join('|')})$`)
const matchImports = /^(.+?)\s+from\s+(?:"([^"]+)"|'([^']+)'|(global))$/
const icssImport = /^:import\((?:"([^"]+)"|'([^']+)')\)/
const VISITED_MARKER = 1
function createParentName(rule, root) {
return `__${root.index(rule.parent)}_${rule.selector}`
}
function serializeImports(imports) {
return imports.map(importPath => '`' + importPath + '`').join(', ')
}
/**
* :import('G') {}
*
* Rule
* composes: ... from 'A'
* composes: ... from 'B'
* Rule
* composes: ... from 'A'
* composes: ... from 'A'
* composes: ... from 'C'
*
* Results in:
*
* graph: {
* G: [],
* A: [],
* B: ['A'],
* C: ['A'],
* }
*/
function addImportToGraph(importId, parentId, graph, visited) {
const siblingsId = parentId + '_' + 'siblings'
const visitedId = parentId + '_' + importId
if (visited[visitedId] !== VISITED_MARKER) {
if (!Array.isArray(visited[siblingsId])) visited[siblingsId] = []
const siblings = visited[siblingsId]
if (Array.isArray(graph[importId]))
graph[importId] = graph[importId].concat(siblings)
else graph[importId] = siblings.slice()
visited[visitedId] = VISITED_MARKER
siblings.push(importId)
}
}
module.exports = postcss.plugin('modules-extract-imports', function(
options = {}
) {
const failOnWrongOrder = options.failOnWrongOrder
return css => {
const graph = {}
const visited = {}
const existingImports = {}
const importDecls = {}
const imports = {}
let importIndex = 0
const createImportedName = typeof options.createImportedName !== 'function'
? (importName /*, path*/) =>
`i__imported_${importName.replace(/\W/g, '_')}_${importIndex++}`
: options.createImportedName
// Check the existing imports order and save refs
css.walkRules(rule => {
const matches = icssImport.exec(rule.selector)
if (matches) {
const [, /*match*/ doubleQuotePath, singleQuotePath] = matches
const importPath = doubleQuotePath || singleQuotePath
addImportToGraph(importPath, 'root', graph, visited)
existingImports[importPath] = rule
}
})
// Find any declaration that supports imports
css.walkDecls(declFilter, decl => {
let matches = decl.value.match(matchImports)
let tmpSymbols
if (matches) {
let [
,
/*match*/ symbols,
doubleQuotePath,
singleQuotePath,
global
] = matches
if (global) {
// Composing globals simply means changing these classes to wrap them in global(name)
tmpSymbols = symbols.split(/\s+/).map(s => `global(${s})`)
} else {
const importPath = doubleQuotePath || singleQuotePath
const parentRule = createParentName(decl.parent, css)
addImportToGraph(importPath, parentRule, graph, visited)
importDecls[importPath] = decl
imports[importPath] = imports[importPath] || {}
tmpSymbols = symbols.split(/\s+/).map(s => {
if (!imports[importPath][s]) {
imports[importPath][s] = createImportedName(s, importPath)
}
return imports[importPath][s]
})
}
decl.value = tmpSymbols.join(' ')
}
})
const importsOrder = topologicalSort(graph, failOnWrongOrder)
if (importsOrder instanceof Error) {
const importPath = importsOrder.nodes.find(importPath =>
importDecls.hasOwnProperty(importPath)
)
const decl = importDecls[importPath]
const errMsg =
'Failed to resolve order of composed modules ' +
serializeImports(importsOrder.nodes) +
'.'
throw decl.error(errMsg, {
plugin: 'modules-extract-imports',
word: 'composes'
})
}
let lastImportRule
importsOrder.forEach(path => {
const importedSymbols = imports[path]
let rule = existingImports[path]
if (!rule && importedSymbols) {
rule = postcss.rule({
selector: `:import("${path}")`,
raws: { after: '\n' }
})
if (lastImportRule) css.insertAfter(lastImportRule, rule)
else css.prepend(rule)
}
lastImportRule = rule
if (!importedSymbols) return
Object.keys(importedSymbols).forEach(importedSymbol => {
rule.append(
postcss.decl({
value: importedSymbol,
prop: importedSymbols[importedSymbol],
raws: { before: '\n ' }
})
)
})
})
}
})
@@ -0,0 +1,54 @@
const PERMANENT_MARKER = 2
const TEMPORARY_MARKER = 1
function createError(node, graph) {
const er = new Error("Nondeterministic import's order")
const related = graph[node]
const relatedNode = related.find(
relatedNode => graph[relatedNode].indexOf(node) > -1
)
er.nodes = [node, relatedNode]
return er
}
function walkGraph(node, graph, state, result, strict) {
if (state[node] === PERMANENT_MARKER) return
if (state[node] === TEMPORARY_MARKER) {
if (strict) return createError(node, graph)
return
}
state[node] = TEMPORARY_MARKER
const children = graph[node]
const length = children.length
for (let i = 0; i < length; ++i) {
const er = walkGraph(children[i], graph, state, result, strict)
if (er instanceof Error) return er
}
state[node] = PERMANENT_MARKER
result.push(node)
}
function topologicalSort(graph, strict) {
const result = []
const state = {}
const nodes = Object.keys(graph)
const length = nodes.length
for (let i = 0; i < length; ++i) {
const er = walkGraph(nodes[i], graph, state, result, strict)
if (er instanceof Error) return er
}
return result
}
module.exports = topologicalSort
@@ -0,0 +1,100 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.0.6] - 2019-03-05
### Fixed
- handles properly selector with escaping characters (like: `.\31 a2b3c { color: red }`)
## [2.0.5] - 2019-02-06
### Fixed
- Path to `index.js`
## [2.0.4] - 2019-01-04
### Fixed
- Inappropriate modification of `steps` function arguments
## [2.0.3] - 2018-12-21
### Fixed
- Don't modify inappropriate animation keywords
## [2.0.2] - 2018-12-05
### Fixed
- Don't break unicode characters.
## [2.0.1] - 2018-11-23
### Fixed
- Handle uppercase `keyframes` at rule.
## [2.0.0] - 2018-11-23
### Changed
- Drop support `nodejs@4`.
- Update `postcss` version to `7`.
## [0.0.11] - 2015-07-19
### Fixed
- Localisation of animation properties.
## [0.0.10] - 2015-06-17
### Added
- Localised at-rules.
## [0.0.9] - 2015-06-12
### Changed
- Using global selectors outside of a global context no longer triggers warnings. Instead, this functionality will be provided by a CSS Modules linter.
### Fixed
- Keyframe rules.
## [0.0.8] - 2015-06-11
### Added
- Pure mode where only local scope is allowed.
### Changed
- Using global selectors outside of a global context now triggers warnings.
## [0.0.7] - 2015-05-30
### Changed
- Migrated to `css-selector-tokenizer`.
## [0.0.6] - 2015-05-28
### Changed
- Renamed project to `postcss-modules-local-by-default`.
## [0.0.5] - 2015-05-22
### Added
- Support for css-loader [inheritance](https://github.com/webpack/css-loader#inheriting) and [local imports](https://github.com/webpack/css-loader#importing-local-class-names).
## [0.0.4] - 2015-05-22
### Changed
- Hide global leak detection behind undocumented `lint` option until it's more robust.
## [0.0.3] - 2015-05-22
### Changed
- Transformer output now uses the new `:local(.identifier)` syntax.
### Added
- Simple global leak detection. Non-local selectors like `input{}` and `[data-foobar]` now throw when not marked as global.
## [0.0.2] - 2015-05-14
### Added
- Support for global selectors appended directly to locals, e.g. `.foo:global(.bar)`
## 0.0.1 - 2015-05-12
### Added
- Automatic local classes
- Explicit global selectors with `:global`
[unreleased]: https://github.com/postcss-modules-local-by-default/compare/v0.0.10...HEAD
[0.0.2]: https://github.com/postcss-modules-local-by-default/compare/v0.0.1...v0.0.2
[0.0.3]: https://github.com/postcss-modules-local-by-default/compare/v0.0.2...v0.0.3
[0.0.4]: https://github.com/postcss-modules-local-by-default/compare/v0.0.3...v0.0.4
[0.0.5]: https://github.com/postcss-modules-local-by-default/compare/v0.0.4...v0.0.5
[0.0.6]: https://github.com/postcss-modules-local-by-default/compare/v0.0.5...v0.0.6
[0.0.7]: https://github.com/postcss-modules-local-by-default/compare/v0.0.6...v0.0.7
[0.0.8]: https://github.com/postcss-modules-local-by-default/compare/v0.0.7...v0.0.8
[0.0.9]: https://github.com/postcss-modules-local-by-default/compare/v0.0.8...v0.0.9
[0.0.10]: https://github.com/postcss-modules-local-by-default/compare/v0.0.9...v0.0.10
[0.0.11]: https://github.com/postcss-modules-local-by-default/compare/v0.0.10...v0.0.11
[2.0.0]: https://github.com/postcss-modules-local-by-default/compare/v1.3.1...v2.0.0
[2.0.1]: https://github.com/postcss-modules-local-by-default/compare/v2.0.0...v2.0.1
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright 2015 Mark Dalgleish <mark.john.dalgleish@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
[![Build Status][ci-img]][ci] [![codecov][codecov-img]][codecov] [![npm][npm-img]][npm]
# CSS Modules: Local by Default
Transformation examples:
```css
.foo { ... } /* => */ :local(.foo) { ... }
.foo .bar { ... } /* => */ :local(.foo) :local(.bar) { ... }
/* Shorthand global selector */
:global .foo .bar { ... } /* => */ .foo .bar { ... }
.foo :global .bar { ... } /* => */ :local(.foo) .bar { ... }
/* Targeted global selector */
:global(.foo) .bar { ... } /* => */ .foo :local(.bar) { ... }
.foo:global(.bar) { ... } /* => */ :local(.foo).bar { ... }
.foo :global(.bar) .baz { ... } /* => */ :local(.foo) .bar :local(.baz) { ... }
.foo:global(.bar) .baz { ... } /* => */ :local(.foo).bar :local(.baz) { ... }
```
## Building
```bash
$ npm install
$ npm test
```
- Build: [![Build Status][ci-img]][ci]
- Lines: [![coveralls][coveralls-img]][coveralls]
- Statements: [![codecov][codecov-img]][codecov]
## Development
```bash
$ npm run autotest
```
## License
MIT
## With thanks
- [Tobias Koppers](https://github.com/sokra)
- [Glen Maddern](https://github.com/geelen)
---
Mark Dalgleish, 2015.
[ci-img]: https://img.shields.io/travis/css-modules/postcss-modules-local-by-default/master.svg?style=flat-square
[ci]: https://travis-ci.org/css-modules/postcss-modules-local-by-default
[npm-img]: https://img.shields.io/npm/v/postcss-modules-local-by-default.svg?style=flat-square
[npm]: https://www.npmjs.com/package/postcss-modules-local-by-default
[coveralls-img]: https://img.shields.io/coveralls/css-modules/postcss-modules-local-by-default/master.svg?style=flat-square
[coveralls]: https://coveralls.io/r/css-modules/postcss-modules-local-by-default?branch=master
[codecov-img]: https://img.shields.io/codecov/c/github/css-modules/postcss-modules-local-by-default/master.svg?style=flat-square
[codecov]: https://codecov.io/github/css-modules/postcss-modules-local-by-default?branch=master
@@ -0,0 +1,502 @@
'use strict';
const postcss = require('postcss');
const selectorParser = require('postcss-selector-parser');
const valueParser = require('postcss-value-parser');
const isSpacing = node => node.type === 'combinator' && node.value === ' ';
function normalizeNodeArray(nodes) {
const array = [];
nodes.forEach(function(x) {
if (Array.isArray(x)) {
normalizeNodeArray(x).forEach(function(item) {
array.push(item);
});
} else if (x) {
array.push(x);
}
});
if (array.length > 0 && isSpacing(array[array.length - 1])) {
array.pop();
}
return array;
}
function localizeNode(rule, mode, options) {
const isScopePseudo = node =>
node.value === ':local' || node.value === ':global';
const transform = (node, context) => {
if (context.ignoreNextSpacing && !isSpacing(node)) {
throw new Error('Missing whitespace after ' + context.ignoreNextSpacing);
}
if (context.enforceNoSpacing && isSpacing(node)) {
throw new Error('Missing whitespace before ' + context.enforceNoSpacing);
}
let newNodes;
switch (node.type) {
case 'root': {
let resultingGlobal;
context.hasPureGlobals = false;
newNodes = node.nodes.map(function(n) {
const nContext = {
global: context.global,
lastWasSpacing: true,
hasLocals: false,
explicit: false,
};
n = transform(n, nContext);
if (typeof resultingGlobal === 'undefined') {
resultingGlobal = nContext.global;
} else if (resultingGlobal !== nContext.global) {
throw new Error(
'Inconsistent rule global/local result in rule "' +
node +
'" (multiple selectors must result in the same mode for the rule)'
);
}
if (!nContext.hasLocals) {
context.hasPureGlobals = true;
}
return n;
});
context.global = resultingGlobal;
node.nodes = normalizeNodeArray(newNodes);
break;
}
case 'selector': {
newNodes = node.map(childNode => transform(childNode, context));
node = node.clone();
node.nodes = normalizeNodeArray(newNodes);
break;
}
case 'combinator': {
if (isSpacing(node)) {
if (context.ignoreNextSpacing) {
context.ignoreNextSpacing = false;
context.lastWasSpacing = false;
context.enforceNoSpacing = false;
return null;
}
context.lastWasSpacing = true;
return node;
}
break;
}
case 'pseudo': {
let childContext;
const isNested = !!node.length;
const isScoped = isScopePseudo(node);
// :local(.foo)
if (isNested) {
if (isScoped) {
if (context.inside) {
throw new Error(
`A ${node.value} is not allowed inside of a ${
context.inside
}(...)`
);
}
childContext = {
global: node.value === ':global',
inside: node.value,
hasLocals: false,
explicit: true,
};
newNodes = node
.map(childNode => transform(childNode, childContext))
.reduce((acc, next) => acc.concat(next.nodes), []);
if (newNodes.length) {
const { before, after } = node.spaces;
const first = newNodes[0];
const last = newNodes[newNodes.length - 1];
first.spaces = { before, after: first.spaces.after };
last.spaces = { before: last.spaces.before, after };
}
node = newNodes;
break;
} else {
childContext = {
global: context.global,
inside: context.inside,
lastWasSpacing: true,
hasLocals: false,
explicit: context.explicit,
};
newNodes = node.map(childNode =>
transform(childNode, childContext)
);
node = node.clone();
node.nodes = normalizeNodeArray(newNodes);
if (childContext.hasLocals) {
context.hasLocals = true;
}
}
break;
//:local .foo .bar
} else if (isScoped) {
if (context.inside) {
throw new Error(
`A ${node.value} is not allowed inside of a ${
context.inside
}(...)`
);
}
const addBackSpacing = !!node.spaces.before;
context.ignoreNextSpacing = context.lastWasSpacing
? node.value
: false;
context.enforceNoSpacing = context.lastWasSpacing
? false
: node.value;
context.global = node.value === ':global';
context.explicit = true;
// because this node has spacing that is lost when we remove it
// we make up for it by adding an extra combinator in since adding
// spacing on the parent selector doesn't work
return addBackSpacing
? selectorParser.combinator({ value: ' ' })
: null;
}
break;
}
case 'id':
case 'class': {
if (!context.global) {
const innerNode = node.clone();
innerNode.spaces = { before: '', after: '' };
node = selectorParser.pseudo({
value: ':local',
nodes: [innerNode],
spaces: node.spaces,
});
context.hasLocals = true;
}
break;
}
}
context.lastWasSpacing = false;
context.ignoreNextSpacing = false;
context.enforceNoSpacing = false;
return node;
};
const rootContext = {
global: mode === 'global',
hasPureGlobals: false,
};
rootContext.selector = selectorParser(root => {
transform(root, rootContext);
}).processSync(rule, { updateSelector: false, lossless: true });
return rootContext;
}
function localizeDeclNode(node, context) {
switch (node.type) {
case 'word':
if (context.localizeNextItem) {
node.value = ':local(' + node.value + ')';
context.localizeNextItem = false;
}
break;
case 'function':
if (
context.options &&
context.options.rewriteUrl &&
node.value.toLowerCase() === 'url'
) {
node.nodes.map(nestedNode => {
if (nestedNode.type !== 'string' && nestedNode.type !== 'word') {
return;
}
let newUrl = context.options.rewriteUrl(
context.global,
nestedNode.value
);
switch (nestedNode.type) {
case 'string':
if (nestedNode.quote === "'") {
newUrl = newUrl.replace(/(\\)/g, '\\$1').replace(/'/g, "\\'");
}
if (nestedNode.quote === '"') {
newUrl = newUrl.replace(/(\\)/g, '\\$1').replace(/"/g, '\\"');
}
break;
case 'word':
newUrl = newUrl.replace(/("|'|\)|\\)/g, '\\$1');
break;
}
nestedNode.value = newUrl;
});
}
break;
}
return node;
}
function isWordAFunctionArgument(wordNode, functionNode) {
return functionNode
? functionNode.nodes.some(
functionNodeChild =>
functionNodeChild.sourceIndex === wordNode.sourceIndex
)
: false;
}
function localizeAnimationShorthandDeclValues(decl, context) {
const validIdent = /^-?[_a-z][_a-z0-9-]*$/i;
/*
The spec defines some keywords that you can use to describe properties such as the timing
function. These are still valid animation names, so as long as there is a property that accepts
a keyword, it is given priority. Only when all the properties that can take a keyword are
exhausted can the animation name be set to the keyword. I.e.
animation: infinite infinite;
The animation will repeat an infinite number of times from the first argument, and will have an
animation name of infinite from the second.
*/
const animationKeywords = {
$alternate: 1,
'$alternate-reverse': 1,
$backwards: 1,
$both: 1,
$ease: 1,
'$ease-in': 1,
'$ease-in-out': 1,
'$ease-out': 1,
$forwards: 1,
$infinite: 1,
$linear: 1,
$none: Infinity, // No matter how many times you write none, it will never be an animation name
$normal: 1,
$paused: 1,
$reverse: 1,
$running: 1,
'$step-end': 1,
'$step-start': 1,
$initial: Infinity,
$inherit: Infinity,
$unset: Infinity,
};
const didParseAnimationName = false;
let parsedAnimationKeywords = {};
let stepsFunctionNode = null;
const valueNodes = valueParser(decl.value).walk(node => {
/* If div-token appeared (represents as comma ','), a possibility of an animation-keywords should be reflesh. */
if (node.type === 'div') {
parsedAnimationKeywords = {};
}
if (node.type === 'function' && node.value.toLowerCase() === 'steps') {
stepsFunctionNode = node;
}
const value =
node.type === 'word' && !isWordAFunctionArgument(node, stepsFunctionNode)
? node.value.toLowerCase()
: null;
let shouldParseAnimationName = false;
if (!didParseAnimationName && value && validIdent.test(value)) {
if ('$' + value in animationKeywords) {
parsedAnimationKeywords['$' + value] =
'$' + value in parsedAnimationKeywords
? parsedAnimationKeywords['$' + value] + 1
: 0;
shouldParseAnimationName =
parsedAnimationKeywords['$' + value] >=
animationKeywords['$' + value];
} else {
shouldParseAnimationName = true;
}
}
const subContext = {
options: context.options,
global: context.global,
localizeNextItem: shouldParseAnimationName && !context.global,
};
return localizeDeclNode(node, subContext);
});
decl.value = valueNodes.toString();
}
function localizeDeclValues(localize, decl, context) {
const valueNodes = valueParser(decl.value);
valueNodes.walk((node, index, nodes) => {
const subContext = {
options: context.options,
global: context.global,
localizeNextItem: localize && !context.global,
};
nodes[index] = localizeDeclNode(node, subContext);
});
decl.value = valueNodes.toString();
}
function localizeDecl(decl, context) {
const isAnimation = /animation$/i.test(decl.prop);
if (isAnimation) {
return localizeAnimationShorthandDeclValues(decl, context);
}
const isAnimationName = /animation(-name)?$/i.test(decl.prop);
if (isAnimationName) {
return localizeDeclValues(true, decl, context);
}
const hasUrl = /url\(/i.test(decl.value);
if (hasUrl) {
return localizeDeclValues(false, decl, context);
}
}
module.exports = postcss.plugin('postcss-modules-local-by-default', function(
options
) {
if (typeof options !== 'object') {
options = {}; // If options is undefined or not an object the plugin fails
}
if (options && options.mode) {
if (
options.mode !== 'global' &&
options.mode !== 'local' &&
options.mode !== 'pure'
) {
throw new Error(
'options.mode must be either "global", "local" or "pure" (default "local")'
);
}
}
const pureMode = options && options.mode === 'pure';
const globalMode = options && options.mode === 'global';
return function(css) {
css.walkAtRules(function(atrule) {
if (/keyframes$/i.test(atrule.name)) {
const globalMatch = /^\s*:global\s*\((.+)\)\s*$/.exec(atrule.params);
const localMatch = /^\s*:local\s*\((.+)\)\s*$/.exec(atrule.params);
let globalKeyframes = globalMode;
if (globalMatch) {
if (pureMode) {
throw atrule.error(
'@keyframes :global(...) is not allowed in pure mode'
);
}
atrule.params = globalMatch[1];
globalKeyframes = true;
} else if (localMatch) {
atrule.params = localMatch[0];
globalKeyframes = false;
} else if (!globalMode) {
atrule.params = ':local(' + atrule.params + ')';
}
atrule.walkDecls(function(decl) {
localizeDecl(decl, {
options: options,
global: globalKeyframes,
});
});
} else if (atrule.nodes) {
atrule.nodes.forEach(function(decl) {
if (decl.type === 'decl') {
localizeDecl(decl, {
options: options,
global: globalMode,
});
}
});
}
});
css.walkRules(function(rule) {
if (
rule.parent.type === 'atrule' &&
/keyframes$/i.test(rule.parent.name)
) {
// ignore keyframe rules
return;
}
if (
rule.nodes &&
rule.selector.slice(0, 2) === '--' &&
rule.selector.slice(-1) === ':'
) {
// ignore custom property set
return;
}
const context = localizeNode(rule, options.mode);
context.options = options;
if (pureMode && context.hasPureGlobals) {
throw rule.error(
'Selector "' +
rule.selector +
'" is not pure ' +
'(pure selectors must contain at least one local class or id)'
);
}
rule.selector = context.selector;
// Less-syntax mixins parse as rules with no nodes
if (rule.nodes) {
rule.nodes.forEach(decl => localizeDecl(decl, context));
}
});
};
});
@@ -0,0 +1,51 @@
{
"name": "postcss-modules-local-by-default",
"version": "2.0.6",
"description": "A CSS Modules transform to make local scope the default",
"main": "index.js",
"engines": {
"node": ">= 6"
},
"keywords": [
"css-modules",
"postcss",
"css",
"postcss-plugin"
],
"author": "Mark Dalgleish",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/css-modules/postcss-modules-local-by-default.git"
},
"prettier": {
"singleQuote": true,
"trailingComma": "es5"
},
"dependencies": {
"postcss": "^7.0.6",
"postcss-selector-parser": "^6.0.0",
"postcss-value-parser": "^3.3.1"
},
"devDependencies": {
"chokidar-cli": "^1.0.1",
"codecov.io": "^0.1.2",
"coveralls": "^3.0.2",
"eslint": "^5.9.0",
"istanbul": "^0.4.5",
"tape": "^4.0.0"
},
"scripts": {
"lint": "eslint index.js test.js",
"pretest": "yarn lint",
"test": "tape test.js",
"autotest": "chokidar index.js test.js -c 'yarn test'",
"precover": "yarn lint",
"cover": "istanbul cover test.js",
"travis": "yarn lint && yarn cover -- --report lcovonly",
"prepublish": "yarn test"
},
"files": [
"index.js"
]
}
@@ -0,0 +1,16 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.2.0] - 2020-03-19
- added the `exportGlobals` option to export global classes and ids
## [2.1.1] - 2019-03-05
### Fixed
- add additional space after the escape sequence (#17)
## [2.1.0] - 2019-03-05
### Fixed
- handles properly selector with escaping characters (like: `.\31 a2b3c { color: red }`)
### Feature
- `generateExportEntry` option (allow to setup key and value for `:export {}` rule)
@@ -0,0 +1,7 @@
ISC License (ISC)
Copyright (c) 2015, Glen Maddern
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,100 @@
# CSS Modules: Scope Locals & Extend
[![Build Status](https://travis-ci.org/css-modules/postcss-modules-scope.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-scope)
Transforms:
```css
:local(.continueButton) {
color: green;
}
```
into:
```css
:export {
continueButton: __buttons_continueButton_djd347adcxz9;
}
.__buttons_continueButton_djd347adcxz9 {
color: green;
}
```
so it doesn't pollute CSS global scope and can be simply used in JS like so:
```js
import styles from './buttons.css'
elem.innerHTML = `<button class="${styles.continueButton}">Continue</button>`
```
## Composition
Since we're exporting class names, there's no reason to export only one. This can give us some really useful reuse of styles:
```css
.globalButtonStyle {
background: white;
border: 1px solid;
border-radius: 0.25rem;
}
.globalButtonStyle:hover {
box-shadow: 0 0 4px -2px;
}
:local(.continueButton) {
compose-with: globalButtonStyle;
color: green;
}
```
becomes:
```
.globalButtonStyle {
background: white;
border: 1px solid;
border-radius: 0.25rem;
}
.globalButtonStyle:hover {
box-shadow: 0 0 4px -2px;
}
:local(.continueButton) {
compose-with: globalButtonStyle;
color: green;
}
```
**Note:** you can also use `composes` as a shorthand for `compose-with`
## Local-by-default & reuse across files
You're looking for [CSS Modules](https://github.com/css-modules/css-modules). It uses this plugin as well as a few others, and it's amazing.
## Building
```
npm install
npm test
```
[![Build Status](https://travis-ci.org/css-modules/postcss-modules-scope.svg?branch=master)](https://travis-ci.org/css-modules/postcss-modules-scope)
* Lines: [![Coverage Status](https://coveralls.io/repos/css-modules/postcss-modules-scope/badge.svg?branch=master)](https://coveralls.io/r/css-modules/postcss-modules-scope?branch=master)
* Statements: [![codecov.io](http://codecov.io/github/css-modules/postcss-modules-scope/coverage.svg?branch=master)](http://codecov.io/github/css-modules/postcss-modules-scope?branch=master)
## Development
- `npm autotest` will watch `src` and `test` for changes and run the tests, and transpile the ES6 to ES5 on success
## License
ISC
## With thanks
- Mark Dalgleish
- Tobias Koppers
- Guy Bedford
---
Glen Maddern, 2015.
@@ -0,0 +1,55 @@
{
"name": "postcss-modules-scope",
"version": "2.2.0",
"description": "A CSS Modules transform to extract export statements from local-scope classes",
"main": "src/index.js",
"engines": {
"node": ">= 6"
},
"scripts": {
"lint": "eslint src test",
"pretest": "yarn lint",
"test": "mocha",
"autotest": "chokidar src test -c 'yarn test'",
"precover": "yarn lint",
"cover": "nyc mocha",
"travis": "yarn cover",
"prepublish": "yarn run test"
},
"repository": {
"type": "git",
"url": "https://github.com/css-modules/postcss-modules-scope.git"
},
"keywords": [
"css-modules",
"postcss",
"plugin"
],
"files": [
"src"
],
"author": "Glen Maddern",
"license": "ISC",
"bugs": {
"url": "https://github.com/css-modules/postcss-modules-scope/issues"
},
"homepage": "https://github.com/css-modules/postcss-modules-scope",
"prettier": {
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
},
"dependencies": {
"postcss": "^7.0.6",
"postcss-selector-parser": "^6.0.0"
},
"devDependencies": {
"cssesc": "^3.0.0",
"chokidar-cli": "^1.0.1",
"codecov.io": "^0.1.2",
"coveralls": "^3.0.2",
"eslint": "^5.9.0",
"mocha": "^6.0.2",
"nyc": "^14.1.0"
}
}
@@ -0,0 +1,315 @@
'use strict';
const postcss = require('postcss');
const selectorParser = require('postcss-selector-parser');
const hasOwnProperty = Object.prototype.hasOwnProperty;
function getSingleLocalNamesForComposes(root) {
return root.nodes.map(node => {
if (node.type !== 'selector' || node.nodes.length !== 1) {
throw new Error(
`composition is only allowed when selector is single :local class name not in "${root}"`
);
}
node = node.nodes[0];
if (
node.type !== 'pseudo' ||
node.value !== ':local' ||
node.nodes.length !== 1
) {
throw new Error(
'composition is only allowed when selector is single :local class name not in "' +
root +
'", "' +
node +
'" is weird'
);
}
node = node.first;
if (node.type !== 'selector' || node.length !== 1) {
throw new Error(
'composition is only allowed when selector is single :local class name not in "' +
root +
'", "' +
node +
'" is weird'
);
}
node = node.first;
if (node.type !== 'class') {
// 'id' is not possible, because you can't compose ids
throw new Error(
'composition is only allowed when selector is single :local class name not in "' +
root +
'", "' +
node +
'" is weird'
);
}
return node.value;
});
}
const whitespace = '[\\x20\\t\\r\\n\\f]';
const unescapeRegExp = new RegExp(
'\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)',
'ig'
);
function unescape(str) {
return str.replace(unescapeRegExp, (_, escaped, escapedWhitespace) => {
const high = '0x' + escaped - 0x10000;
// NaN means non-codepoint
// Workaround erroneous numeric interpretation of +"0x"
return high !== high || escapedWhitespace
? escaped
: high < 0
? // BMP codepoint
String.fromCharCode(high + 0x10000)
: // Supplemental Plane codepoint (surrogate pair)
String.fromCharCode((high >> 10) | 0xd800, (high & 0x3ff) | 0xdc00);
});
}
const processor = postcss.plugin('postcss-modules-scope', function(options) {
return css => {
const generateScopedName =
(options && options.generateScopedName) || processor.generateScopedName;
const generateExportEntry =
(options && options.generateExportEntry) || processor.generateExportEntry;
const exportGlobals = options && options.exportGlobals;
const exports = Object.create(null);
function exportScopedName(name, rawName) {
const scopedName = generateScopedName(
rawName ? rawName : name,
css.source.input.from,
css.source.input.css
);
const exportEntry = generateExportEntry(
rawName ? rawName : name,
scopedName,
css.source.input.from,
css.source.input.css
);
const { key, value } = exportEntry;
exports[key] = exports[key] || [];
if (exports[key].indexOf(value) < 0) {
exports[key].push(value);
}
return scopedName;
}
function localizeNode(node) {
switch (node.type) {
case 'selector':
node.nodes = node.map(localizeNode);
return node;
case 'class':
return selectorParser.className({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
case 'id': {
return selectorParser.id({
value: exportScopedName(
node.value,
node.raws && node.raws.value ? node.raws.value : null
),
});
}
}
throw new Error(
`${node.type} ("${node}") is not allowed in a :local block`
);
}
function traverseNode(node) {
switch (node.type) {
case 'pseudo':
if (node.value === ':local') {
if (node.nodes.length !== 1) {
throw new Error('Unexpected comma (",") in :local block');
}
const selector = localizeNode(node.first, node.spaces);
// move the spaces that were around the psuedo selector to the first
// non-container node
selector.first.spaces = node.spaces;
const nextNode = node.next();
if (
nextNode &&
nextNode.type === 'combinator' &&
nextNode.value === ' ' &&
/\\[A-F0-9]{1,6}$/.test(selector.last.value)
) {
selector.last.spaces.after = ' ';
}
node.replaceWith(selector);
return;
}
/* falls through */
case 'root':
case 'selector': {
node.each(traverseNode);
break;
}
case 'id':
case 'class':
if (exportGlobals) {
exports[node.value] = [node.value];
}
break;
}
return node;
}
// Find any :import and remember imported names
const importedNames = {};
css.walkRules(rule => {
if (/^:import\(.+\)$/.test(rule.selector)) {
rule.walkDecls(decl => {
importedNames[decl.prop] = true;
});
}
});
// Find any :local classes
css.walkRules(rule => {
if (
rule.nodes &&
rule.selector.slice(0, 2) === '--' &&
rule.selector.slice(-1) === ':'
) {
// ignore custom property set
return;
}
let parsedSelector = selectorParser().astSync(rule);
rule.selector = traverseNode(parsedSelector.clone()).toString();
rule.walkDecls(/composes|compose-with/, decl => {
const localNames = getSingleLocalNamesForComposes(parsedSelector);
const classes = decl.value.split(/\s+/);
classes.forEach(className => {
const global = /^global\(([^\)]+)\)$/.exec(className);
if (global) {
localNames.forEach(exportedName => {
exports[exportedName].push(global[1]);
});
} else if (hasOwnProperty.call(importedNames, className)) {
localNames.forEach(exportedName => {
exports[exportedName].push(className);
});
} else if (hasOwnProperty.call(exports, className)) {
localNames.forEach(exportedName => {
exports[className].forEach(item => {
exports[exportedName].push(item);
});
});
} else {
throw decl.error(
`referenced class name "${className}" in ${decl.prop} not found`
);
}
});
decl.remove();
});
rule.walkDecls(decl => {
let tokens = decl.value.split(/(,|'[^']*'|"[^"]*")/);
tokens = tokens.map((token, idx) => {
if (idx === 0 || tokens[idx - 1] === ',') {
const localMatch = /^(\s*):local\s*\((.+?)\)/.exec(token);
if (localMatch) {
return (
localMatch[1] +
exportScopedName(localMatch[2]) +
token.substr(localMatch[0].length)
);
} else {
return token;
}
} else {
return token;
}
});
decl.value = tokens.join('');
});
});
// Find any :local keyframes
css.walkAtRules(atrule => {
if (/keyframes$/i.test(atrule.name)) {
const localMatch = /^\s*:local\s*\((.+?)\)\s*$/.exec(atrule.params);
if (localMatch) {
atrule.params = exportScopedName(localMatch[1]);
}
}
});
// If we found any :locals, insert an :export rule
const exportedNames = Object.keys(exports);
if (exportedNames.length > 0) {
const exportRule = postcss.rule({ selector: ':export' });
exportedNames.forEach(exportedName =>
exportRule.append({
prop: exportedName,
value: exports[exportedName].join(' '),
raws: { before: '\n ' },
})
);
css.append(exportRule);
}
};
});
processor.generateScopedName = function(name, path) {
const sanitisedPath = path
.replace(/\.[^\.\/\\]+$/, '')
.replace(/[\W_]+/g, '_')
.replace(/^_|_$/g, '');
return `_${sanitisedPath}__${name}`.trim();
};
processor.generateExportEntry = function(name, scopedName) {
return {
key: unescape(name),
value: unescape(scopedName),
};
};
module.exports = processor;
@@ -0,0 +1,7 @@
ISC License (ISC)
Copyright (c) 2015, Glen Maddern
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,77 @@
# CSS Modules: Values
Pass arbitrary values between your module files
### Usage
```css
/* colors.css */
@value primary: #BF4040;
@value secondary: #1F4F7F;
.text-primary {
color: primary;
}
.text-secondary {
color: secondary;
}
```
```css
/* breakpoints.css */
@value small: (max-width: 599px);
@value medium: (min-width: 600px) and (max-width: 959px);
@value large: (min-width: 960px);
```
```css
/* my-component.css */
/* alias paths for other values or composition */
@value colors: "./colors.css";
/* import multiple from a single file */
@value primary, secondary from colors;
/* make local aliases to imported values */
@value small as bp-small, large as bp-large from "./breakpoints.css";
.header {
composes: text-primary from colors;
box-shadow: 0 0 10px secondary;
}
@media bp-small {
.header {
box-shadow: 0 0 4px secondary;
}
}
@media bp-large {
.header {
box-shadow: 0 0 20px secondary;
}
}
```
**If you are using Sass** along with this PostCSS plugin, do not use the colon `:` in your `@value` definitions. It will cause Sass to crash.
Note also you can _import_ multiple values at once but can only _define_ one value per line.
```css
@value a: b, c: d; /* defines a as "b, c: d" */
```
### Justification
See [this PR](https://github.com/css-modules/css-modules-loader-core/pull/28) for more background
## License
ISC
## With thanks
- Mark Dalgleish
- Tobias Koppers
- Josh Johnston
---
Glen Maddern, 2015.
@@ -0,0 +1,45 @@
{
"name": "postcss-modules-values",
"version": "2.0.0",
"description": "PostCSS plugin for CSS Modules to pass arbitrary values between your module files",
"main": "src/index.js",
"files": [
"src"
],
"scripts": {
"lint": "eslint src test",
"pretest": "yarn lint",
"test": "mocha",
"autotest": "chokidar src test -c 'npm test'",
"cover": "nyc mocha",
"travis": "yarn lint && yarn cover",
"prepublish": "yarn test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/css-modules/postcss-modules-values.git"
},
"keywords": [
"css",
"modules",
"postcss"
],
"author": "Glen Maddern",
"license": "ISC",
"bugs": {
"url": "https://github.com/css-modules/postcss-modules-values/issues"
},
"homepage": "https://github.com/css-modules/postcss-modules-values#readme",
"devDependencies": {
"chokidar-cli": "^1.0.1",
"codecov.io": "^0.1.2",
"coveralls": "^3.0.2",
"mocha": "^5.2.0",
"eslint": "^5.9.0",
"nyc": "^13.1.0"
},
"dependencies": {
"icss-replace-symbols": "^1.1.0",
"postcss": "^7.0.6"
}
}
@@ -0,0 +1,119 @@
'use strict';
const postcss = require('postcss');
const ICSSReplaceSymbols = require('icss-replace-symbols');
const replaceSymbols = require('icss-replace-symbols');
const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/;
const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g;
const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/;
let options = {};
let importIndex = 0;
let createImportedName =
(options && options.createImportedName) ||
((importName /*, path*/) =>
`i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`);
module.exports = postcss.plugin(
'postcss-modules-values',
() => (css, result) => {
const importAliases = [];
const definitions = {};
const addDefinition = atRule => {
let matches;
while ((matches = matchValueDefinition.exec(atRule.params))) {
let [, /*match*/ key, value] = matches;
// Add to the definitions, knowing that values can refer to each other
definitions[key] = replaceSymbols.replaceAll(definitions, value);
atRule.remove();
}
};
const addImport = atRule => {
const matches = matchImports.exec(atRule.params);
if (matches) {
let [, /*match*/ aliases, path] = matches;
// We can use constants for path names
if (definitions[path]) {
path = definitions[path];
}
const imports = aliases
.replace(/^\(\s*([\s\S]+)\s*\)$/, '$1')
.split(/\s*,\s*/)
.map(alias => {
const tokens = matchImport.exec(alias);
if (tokens) {
const [, /*match*/ theirName, myName = theirName] = tokens;
const importedName = createImportedName(myName);
definitions[myName] = importedName;
return { theirName, importedName };
} else {
throw new Error(`@import statement "${alias}" is invalid!`);
}
});
importAliases.push({ path, imports });
atRule.remove();
}
};
/* Look at all the @value statements and treat them as locals or as imports */
css.walkAtRules('value', atRule => {
if (matchImports.exec(atRule.params)) {
addImport(atRule);
} else {
if (atRule.params.indexOf('@value') !== -1) {
result.warn('Invalid value definition: ' + atRule.params);
}
addDefinition(atRule);
}
});
/* We want to export anything defined by now, but don't add it to the CSS yet or
it well get picked up by the replacement stuff */
const exportDeclarations = Object.keys(definitions).map(key =>
postcss.decl({
value: definitions[key],
prop: key,
raws: { before: '\n ' }
})
);
/* If we have no definitions, don't continue */
if (!Object.keys(definitions).length) {
return;
}
/* Perform replacements */
ICSSReplaceSymbols.default(css, definitions);
/* Add export rules if any */
if (exportDeclarations.length > 0) {
const exportRule = postcss.rule({
selector: ':export',
raws: { after: '\n' }
});
exportRule.append(exportDeclarations);
css.prepend(exportRule);
}
/* Add import rules */
importAliases.reverse().forEach(({ path, imports }) => {
const importRule = postcss.rule({
selector: `:import(${path})`,
raws: { after: '\n' }
});
imports.forEach(({ theirName, importedName }) => {
importRule.append({
value: theirName,
prop: importedName,
raws: { before: '\n ' }
});
});
css.prepend(importRule);
});
}
);
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright 2013 Andrey Sitnik <andrey@sitnik.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+43
View File
@@ -0,0 +1,43 @@
# PostCSS [![Gitter][chat-img]][chat]
<img align="right" width="95" height="95"
alt="Philosophers stone, logo of PostCSS"
src="http://postcss.github.io/postcss/logo.svg">
[chat-img]: https://img.shields.io/badge/Gitter-Join_the_PostCSS_chat-brightgreen.svg
[chat]: https://gitter.im/postcss/postcss
PostCSS is a tool for transforming styles with JS plugins.
These plugins can lint your CSS, support variables and mixins,
transpile future CSS syntax, inline images, and more.
PostCSS is used by industry leaders including Wikipedia, Twitter, Alibaba,
and JetBrains. The [Autoprefixer] PostCSS plugin is one of the most popular
CSS processors.
PostCSS takes a CSS file and provides an API to analyze and modify its rules
(by transforming them into an [Abstract Syntax Tree]).
This API can then be used by [plugins] to do a lot of useful things,
e.g. to find errors automatically insert vendor prefixes.
**Support / Discussion:** [Gitter](https://gitter.im/postcss/postcss)<br>
**Twitter account:** [@postcss](https://twitter.com/postcss)<br>
**VK.com page:** [postcss](https://vk.com/postcss)<br>
**中文翻译**: [`README-cn.md`](./README-cn.md)
For PostCSS commercial support (consulting, improving the front-end culture
of your company, PostCSS plugins), contact [Evil Martians]
at <surrender@evilmartians.com>.
[Abstract Syntax Tree]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
[Evil Martians]: https://evilmartians.com/?utm_source=postcss
[Autoprefixer]: https://github.com/postcss/autoprefixer
[plugins]: https://github.com/postcss/postcss#plugins
<a href="https://evilmartians.com/?utm_source=postcss">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>
## Docs
Read **[full docs](https://github.com/postcss/postcss#readme)** on GitHub.
+127
View File
@@ -0,0 +1,127 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _container = _interopRequireDefault(require("./container"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
/**
* Represents an at-rule.
*
* If its followed in the CSS by a {} block, this node will have
* a nodes property representing its children.
*
* @extends Container
*
* @example
* const root = postcss.parse('@charset "UTF-8"; @media print {}')
*
* const charset = root.first
* charset.type //=> 'atrule'
* charset.nodes //=> undefined
*
* const media = root.last
* media.nodes //=> []
*/
var AtRule = /*#__PURE__*/function (_Container) {
_inheritsLoose(AtRule, _Container);
function AtRule(defaults) {
var _this;
_this = _Container.call(this, defaults) || this;
_this.type = 'atrule';
return _this;
}
var _proto = AtRule.prototype;
_proto.append = function append() {
var _Container$prototype$;
if (!this.nodes) this.nodes = [];
for (var _len = arguments.length, children = new Array(_len), _key = 0; _key < _len; _key++) {
children[_key] = arguments[_key];
}
return (_Container$prototype$ = _Container.prototype.append).call.apply(_Container$prototype$, [this].concat(children));
};
_proto.prepend = function prepend() {
var _Container$prototype$2;
if (!this.nodes) this.nodes = [];
for (var _len2 = arguments.length, children = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
children[_key2] = arguments[_key2];
}
return (_Container$prototype$2 = _Container.prototype.prepend).call.apply(_Container$prototype$2, [this].concat(children));
}
/**
* @memberof AtRule#
* @member {string} name The at-rules name immediately follows the `@`.
*
* @example
* const root = postcss.parse('@media print {}')
* media.name //=> 'media'
* const media = root.first
*/
/**
* @memberof AtRule#
* @member {string} params The at-rules parameters, the values
* that follow the at-rules name but precede
* any {} block.
*
* @example
* const root = postcss.parse('@media print, screen {}')
* const media = root.first
* media.params //=> 'print, screen'
*/
/**
* @memberof AtRule#
* @member {object} raws Information to generate byte-to-byte equal
* node string as it was in the origin input.
*
* Every parser saves its own properties,
* but the default CSS parser uses:
*
* * `before`: the space symbols before the node. It also stores `*`
* and `_` symbols before the declaration (IE hack).
* * `after`: the space symbols after the last child of the node
* to the end of the node.
* * `between`: the symbols between the property and value
* for declarations, selector and `{` for rules, or last parameter
* and `{` for at-rules.
* * `semicolon`: contains true if the last child has
* an (optional) semicolon.
* * `afterName`: the space between the at-rule name and its parameters.
*
* PostCSS cleans at-rule parameters from comments and extra spaces,
* but it stores origin content in raws properties.
* As such, if you dont change a declarations value,
* PostCSS will use the raw value with comments.
*
* @example
* const root = postcss.parse(' @media\nprint {\n}')
* root.first.first.raws //=> { before: ' ',
* // between: ' ',
* // afterName: '\n',
* // after: '\n' }
*/
;
return AtRule;
}(_container.default);
var _default = AtRule;
exports.default = _default;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImF0LXJ1bGUuZXM2Il0sIm5hbWVzIjpbIkF0UnVsZSIsImRlZmF1bHRzIiwidHlwZSIsImFwcGVuZCIsIm5vZGVzIiwiY2hpbGRyZW4iLCJwcmVwZW5kIiwiQ29udGFpbmVyIl0sIm1hcHBpbmdzIjoiOzs7OztBQUFBOzs7Ozs7QUFFQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBa0JNQSxNOzs7QUFDSixrQkFBYUMsUUFBYixFQUF1QjtBQUFBOztBQUNyQixrQ0FBTUEsUUFBTjtBQUNBLFVBQUtDLElBQUwsR0FBWSxRQUFaO0FBRnFCO0FBR3RCOzs7O1NBRURDLE0sR0FBQSxrQkFBcUI7QUFBQTs7QUFDbkIsUUFBSSxDQUFDLEtBQUtDLEtBQVYsRUFBaUIsS0FBS0EsS0FBTCxHQUFhLEVBQWI7O0FBREUsc0NBQVZDLFFBQVU7QUFBVkEsTUFBQUEsUUFBVTtBQUFBOztBQUVuQix5REFBYUYsTUFBYixrREFBdUJFLFFBQXZCO0FBQ0QsRzs7U0FFREMsTyxHQUFBLG1CQUFzQjtBQUFBOztBQUNwQixRQUFJLENBQUMsS0FBS0YsS0FBVixFQUFpQixLQUFLQSxLQUFMLEdBQWEsRUFBYjs7QUFERyx1Q0FBVkMsUUFBVTtBQUFWQSxNQUFBQSxRQUFVO0FBQUE7O0FBRXBCLDBEQUFhQyxPQUFiLG1EQUF3QkQsUUFBeEI7QUFDRDtBQUVEOzs7Ozs7Ozs7O0FBVUE7Ozs7Ozs7Ozs7OztBQVlBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBdENtQkUsa0I7O2VBdUVOUCxNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENvbnRhaW5lciBmcm9tICcuL2NvbnRhaW5lcidcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIGF0LXJ1bGUuXG4gKlxuICogSWYgaXTigJlzIGZvbGxvd2VkIGluIHRoZSBDU1MgYnkgYSB7fSBibG9jaywgdGhpcyBub2RlIHdpbGwgaGF2ZVxuICogYSBub2RlcyBwcm9wZXJ0eSByZXByZXNlbnRpbmcgaXRzIGNoaWxkcmVuLlxuICpcbiAqIEBleHRlbmRzIENvbnRhaW5lclxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCByb290ID0gcG9zdGNzcy5wYXJzZSgnQGNoYXJzZXQgXCJVVEYtOFwiOyBAbWVkaWEgcHJpbnQge30nKVxuICpcbiAqIGNvbnN0IGNoYXJzZXQgPSByb290LmZpcnN0XG4gKiBjaGFyc2V0LnR5cGUgIC8vPT4gJ2F0cnVsZSdcbiAqIGNoYXJzZXQubm9kZXMgLy89PiB1bmRlZmluZWRcbiAqXG4gKiBjb25zdCBtZWRpYSA9IHJvb3QubGFzdFxuICogbWVkaWEubm9kZXMgICAvLz0+IFtdXG4gKi9cbmNsYXNzIEF0UnVsZSBleHRlbmRzIENvbnRhaW5lciB7XG4gIGNvbnN0cnVjdG9yIChkZWZhdWx0cykge1xuICAgIHN1cGVyKGRlZmF1bHRzKVxuICAgIHRoaXMudHlwZSA9ICdhdHJ1bGUnXG4gIH1cblxuICBhcHBlbmQgKC4uLmNoaWxkcmVuKSB7XG4gICAgaWYgKCF0aGlzLm5vZGVzKSB0aGlzLm5vZGVzID0gW11cbiAgICByZXR1cm4gc3VwZXIuYXBwZW5kKC4uLmNoaWxkcmVuKVxuICB9XG5cbiAgcHJlcGVuZCAoLi4uY2hpbGRyZW4pIHtcbiAgICBpZiAoIXRoaXMubm9kZXMpIHRoaXMubm9kZXMgPSBbXVxuICAgIHJldHVybiBzdXBlci5wcmVwZW5kKC4uLmNoaWxkcmVuKVxuICB9XG5cbiAgLyoqXG4gICAqIEBtZW1iZXJvZiBBdFJ1bGUjXG4gICAqIEBtZW1iZXIge3N0cmluZ30gbmFtZSBUaGUgYXQtcnVsZeKAmXMgbmFtZSBpbW1lZGlhdGVseSBmb2xsb3dzIHRoZSBgQGAuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvb3QgID0gcG9zdGNzcy5wYXJzZSgnQG1lZGlhIHByaW50IHt9JylcbiAgICogbWVkaWEubmFtZSAvLz0+ICdtZWRpYSdcbiAgICogY29uc3QgbWVkaWEgPSByb290LmZpcnN0XG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWVtYmVyb2YgQXRSdWxlI1xuICAgKiBAbWVtYmVyIHtzdHJpbmd9IHBhcmFtcyBUaGUgYXQtcnVsZeKAmXMgcGFyYW1ldGVycywgdGhlIHZhbHVlc1xuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0IGZvbGxvdyB0aGUgYXQtcnVsZeKAmXMgbmFtZSBidXQgcHJlY2VkZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICBhbnkge30gYmxvY2suXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvb3QgID0gcG9zdGNzcy5wYXJzZSgnQG1lZGlhIHByaW50LCBzY3JlZW4ge30nKVxuICAgKiBjb25zdCBtZWRpYSA9IHJvb3QuZmlyc3RcbiAgICogbWVkaWEucGFyYW1zIC8vPT4gJ3ByaW50LCBzY3JlZW4nXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWVtYmVyb2YgQXRSdWxlI1xuICAgKiBAbWVtYmVyIHtvYmplY3R9IHJhd3MgSW5mb3JtYXRpb24gdG8gZ2VuZXJhdGUgYnl0ZS10by1ieXRlIGVxdWFsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgbm9kZSBzdHJpbmcgYXMgaXQgd2FzIGluIHRoZSBvcmlnaW4gaW5wdXQuXG4gICAqXG4gICAqIEV2ZXJ5IHBhcnNlciBzYXZlcyBpdHMgb3duIHByb3BlcnRpZXMsXG4gICAqIGJ1dCB0aGUgZGVmYXVsdCBDU1MgcGFyc2VyIHVzZXM6XG4gICAqXG4gICAqICogYGJlZm9yZWA6IHRoZSBzcGFjZSBzeW1ib2xzIGJlZm9yZSB0aGUgbm9kZS4gSXQgYWxzbyBzdG9yZXMgYCpgXG4gICAqICAgYW5kIGBfYCBzeW1ib2xzIGJlZm9yZSB0aGUgZGVjbGFyYXRpb24gKElFIGhhY2spLlxuICAgKiAqIGBhZnRlcmA6IHRoZSBzcGFjZSBzeW1ib2xzIGFmdGVyIHRoZSBsYXN0IGNoaWxkIG9mIHRoZSBub2RlXG4gICAqICAgdG8gdGhlIGVuZCBvZiB0aGUgbm9kZS5cbiAgICogKiBgYmV0d2VlbmA6IHRoZSBzeW1ib2xzIGJldHdlZW4gdGhlIHByb3BlcnR5IGFuZCB2YWx1ZVxuICAgKiAgIGZvciBkZWNsYXJhdGlvbnMsIHNlbGVjdG9yIGFuZCBge2AgZm9yIHJ1bGVzLCBvciBsYXN0IHBhcmFtZXRlclxuICAgKiAgIGFuZCBge2AgZm9yIGF0LXJ1bGVzLlxuICAgKiAqIGBzZW1pY29sb25gOiBjb250YWlucyB0cnVlIGlmIHRoZSBsYXN0IGNoaWxkIGhhc1xuICAgKiAgIGFuIChvcHRpb25hbCkgc2VtaWNvbG9uLlxuICAgKiAqIGBhZnRlck5hbWVgOiB0aGUgc3BhY2UgYmV0d2VlbiB0aGUgYXQtcnVsZSBuYW1lIGFuZCBpdHMgcGFyYW1ldGVycy5cbiAgICpcbiAgICogUG9zdENTUyBjbGVhbnMgYXQtcnVsZSBwYXJhbWV0ZXJzIGZyb20gY29tbWVudHMgYW5kIGV4dHJhIHNwYWNlcyxcbiAgICogYnV0IGl0IHN0b3JlcyBvcmlnaW4gY29udGVudCBpbiByYXdzIHByb3BlcnRpZXMuXG4gICAqIEFzIHN1Y2gsIGlmIHlvdSBkb27igJl0IGNoYW5nZSBhIGRlY2xhcmF0aW9u4oCZcyB2YWx1ZSxcbiAgICogUG9zdENTUyB3aWxsIHVzZSB0aGUgcmF3IHZhbHVlIHdpdGggY29tbWVudHMuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvb3QgPSBwb3N0Y3NzLnBhcnNlKCcgIEBtZWRpYVxcbnByaW50IHtcXG59JylcbiAgICogcm9vdC5maXJzdC5maXJzdC5yYXdzIC8vPT4geyBiZWZvcmU6ICcgICcsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgYmV0d2VlbjogJyAnLFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGFmdGVyTmFtZTogJ1xcbicsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgYWZ0ZXI6ICdcXG4nIH1cbiAgICovXG59XG5cbmV4cG9ydCBkZWZhdWx0IEF0UnVsZVxuIl0sImZpbGUiOiJhdC1ydWxlLmpzIn0=
+55
View File
@@ -0,0 +1,55 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _node = _interopRequireDefault(require("./node"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
/**
* Represents a comment between declarations or statements (rule and at-rules).
*
* Comments inside selectors, at-rule parameters, or declaration values
* will be stored in the `raws` properties explained above.
*
* @extends Node
*/
var Comment = /*#__PURE__*/function (_Node) {
_inheritsLoose(Comment, _Node);
function Comment(defaults) {
var _this;
_this = _Node.call(this, defaults) || this;
_this.type = 'comment';
return _this;
}
/**
* @memberof Comment#
* @member {string} text The comments text.
*/
/**
* @memberof Comment#
* @member {object} raws Information to generate byte-to-byte equal
* node string as it was in the origin input.
*
* Every parser saves its own properties,
* but the default CSS parser uses:
*
* * `before`: the space symbols before the node.
* * `left`: the space symbols between `/*` and the comments text.
* * `right`: the space symbols between the comments text.
*/
return Comment;
}(_node.default);
var _default = Comment;
exports.default = _default;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbW1lbnQuZXM2Il0sIm5hbWVzIjpbIkNvbW1lbnQiLCJkZWZhdWx0cyIsInR5cGUiLCJOb2RlIl0sIm1hcHBpbmdzIjoiOzs7OztBQUFBOzs7Ozs7QUFFQTs7Ozs7Ozs7SUFRTUEsTzs7O0FBQ0osbUJBQWFDLFFBQWIsRUFBdUI7QUFBQTs7QUFDckIsNkJBQU1BLFFBQU47QUFDQSxVQUFLQyxJQUFMLEdBQVksU0FBWjtBQUZxQjtBQUd0QjtBQUVEOzs7OztBQUtBOzs7Ozs7Ozs7Ozs7Ozs7RUFYb0JDLGE7O2VBeUJQSCxPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IE5vZGUgZnJvbSAnLi9ub2RlJ1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBjb21tZW50IGJldHdlZW4gZGVjbGFyYXRpb25zIG9yIHN0YXRlbWVudHMgKHJ1bGUgYW5kIGF0LXJ1bGVzKS5cbiAqXG4gKiBDb21tZW50cyBpbnNpZGUgc2VsZWN0b3JzLCBhdC1ydWxlIHBhcmFtZXRlcnMsIG9yIGRlY2xhcmF0aW9uIHZhbHVlc1xuICogd2lsbCBiZSBzdG9yZWQgaW4gdGhlIGByYXdzYCBwcm9wZXJ0aWVzIGV4cGxhaW5lZCBhYm92ZS5cbiAqXG4gKiBAZXh0ZW5kcyBOb2RlXG4gKi9cbmNsYXNzIENvbW1lbnQgZXh0ZW5kcyBOb2RlIHtcbiAgY29uc3RydWN0b3IgKGRlZmF1bHRzKSB7XG4gICAgc3VwZXIoZGVmYXVsdHMpXG4gICAgdGhpcy50eXBlID0gJ2NvbW1lbnQnXG4gIH1cblxuICAvKipcbiAgICogQG1lbWJlcm9mIENvbW1lbnQjXG4gICAqIEBtZW1iZXIge3N0cmluZ30gdGV4dCBUaGUgY29tbWVudOKAmXMgdGV4dC5cbiAgICovXG5cbiAgLyoqXG4gICAqIEBtZW1iZXJvZiBDb21tZW50I1xuICAgKiBAbWVtYmVyIHtvYmplY3R9IHJhd3MgSW5mb3JtYXRpb24gdG8gZ2VuZXJhdGUgYnl0ZS10by1ieXRlIGVxdWFsXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBub2RlIHN0cmluZyBhcyBpdCB3YXMgaW4gdGhlIG9yaWdpbiBpbnB1dC5cbiAgICpcbiAgICogRXZlcnkgcGFyc2VyIHNhdmVzIGl0cyBvd24gcHJvcGVydGllcyxcbiAgICogYnV0IHRoZSBkZWZhdWx0IENTUyBwYXJzZXIgdXNlczpcbiAgICpcbiAgICogKiBgYmVmb3JlYDogdGhlIHNwYWNlIHN5bWJvbHMgYmVmb3JlIHRoZSBub2RlLlxuICAgKiAqIGBsZWZ0YDogdGhlIHNwYWNlIHN5bWJvbHMgYmV0d2VlbiBgLypgIGFuZCB0aGUgY29tbWVudOKAmXMgdGV4dC5cbiAgICogKiBgcmlnaHRgOiB0aGUgc3BhY2Ugc3ltYm9scyBiZXR3ZWVuIHRoZSBjb21tZW504oCZcyB0ZXh0LlxuICAgKi9cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29tbWVudFxuIl0sImZpbGUiOiJjb21tZW50LmpzIn0=
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,96 @@
"use strict";
exports.__esModule = true;
exports.default = void 0;
var _node = _interopRequireDefault(require("./node"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
/**
* Represents a CSS declaration.
*
* @extends Node
*
* @example
* const root = postcss.parse('a { color: black }')
* const decl = root.first.first
* decl.type //=> 'decl'
* decl.toString() //=> ' color: black'
*/
var Declaration = /*#__PURE__*/function (_Node) {
_inheritsLoose(Declaration, _Node);
function Declaration(defaults) {
var _this;
_this = _Node.call(this, defaults) || this;
_this.type = 'decl';
return _this;
}
/**
* @memberof Declaration#
* @member {string} prop The declarations property name.
*
* @example
* const root = postcss.parse('a { color: black }')
* const decl = root.first.first
* decl.prop //=> 'color'
*/
/**
* @memberof Declaration#
* @member {string} value The declarations value.
*
* @example
* const root = postcss.parse('a { color: black }')
* const decl = root.first.first
* decl.value //=> 'black'
*/
/**
* @memberof Declaration#
* @member {boolean} important `true` if the declaration
* has an !important annotation.
*
* @example
* const root = postcss.parse('a { color: black !important; color: red }')
* root.first.first.important //=> true
* root.first.last.important //=> undefined
*/
/**
* @memberof Declaration#
* @member {object} raws Information to generate byte-to-byte equal
* node string as it was in the origin input.
*
* Every parser saves its own properties,
* but the default CSS parser uses:
*
* * `before`: the space symbols before the node. It also stores `*`
* and `_` symbols before the declaration (IE hack).
* * `between`: the symbols between the property and value
* for declarations.
* * `important`: the content of the important statement,
* if it is not just `!important`.
*
* PostCSS cleans declaration from comments and extra spaces,
* but it stores origin content in raws properties.
* As such, if you dont change a declarations value,
* PostCSS will use the raw value with comments.
*
* @example
* const root = postcss.parse('a {\n color:black\n}')
* root.first.first.raws //=> { before: '\n ', between: ':' }
*/
return Declaration;
}(_node.default);
var _default = Declaration;
exports.default = _default;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImRlY2xhcmF0aW9uLmVzNiJdLCJuYW1lcyI6WyJEZWNsYXJhdGlvbiIsImRlZmF1bHRzIiwidHlwZSIsIk5vZGUiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUE7Ozs7OztBQUVBOzs7Ozs7Ozs7OztJQVdNQSxXOzs7QUFDSix1QkFBYUMsUUFBYixFQUF1QjtBQUFBOztBQUNyQiw2QkFBTUEsUUFBTjtBQUNBLFVBQUtDLElBQUwsR0FBWSxNQUFaO0FBRnFCO0FBR3RCO0FBRUQ7Ozs7Ozs7Ozs7QUFVQTs7Ozs7Ozs7OztBQVVBOzs7Ozs7Ozs7OztBQVdBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFyQ3dCQyxhOztlQStEWEgsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBOb2RlIGZyb20gJy4vbm9kZSdcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgQ1NTIGRlY2xhcmF0aW9uLlxuICpcbiAqIEBleHRlbmRzIE5vZGVcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3Qgcm9vdCA9IHBvc3Rjc3MucGFyc2UoJ2EgeyBjb2xvcjogYmxhY2sgfScpXG4gKiBjb25zdCBkZWNsID0gcm9vdC5maXJzdC5maXJzdFxuICogZGVjbC50eXBlICAgICAgIC8vPT4gJ2RlY2wnXG4gKiBkZWNsLnRvU3RyaW5nKCkgLy89PiAnIGNvbG9yOiBibGFjaydcbiAqL1xuY2xhc3MgRGVjbGFyYXRpb24gZXh0ZW5kcyBOb2RlIHtcbiAgY29uc3RydWN0b3IgKGRlZmF1bHRzKSB7XG4gICAgc3VwZXIoZGVmYXVsdHMpXG4gICAgdGhpcy50eXBlID0gJ2RlY2wnXG4gIH1cblxuICAvKipcbiAgICogQG1lbWJlcm9mIERlY2xhcmF0aW9uI1xuICAgKiBAbWVtYmVyIHtzdHJpbmd9IHByb3AgVGhlIGRlY2xhcmF0aW9u4oCZcyBwcm9wZXJ0eSBuYW1lLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBjb25zdCByb290ID0gcG9zdGNzcy5wYXJzZSgnYSB7IGNvbG9yOiBibGFjayB9JylcbiAgICogY29uc3QgZGVjbCA9IHJvb3QuZmlyc3QuZmlyc3RcbiAgICogZGVjbC5wcm9wIC8vPT4gJ2NvbG9yJ1xuICAgKi9cblxuICAvKipcbiAgICogQG1lbWJlcm9mIERlY2xhcmF0aW9uI1xuICAgKiBAbWVtYmVyIHtzdHJpbmd9IHZhbHVlIFRoZSBkZWNsYXJhdGlvbuKAmXMgdmFsdWUuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGNvbnN0IHJvb3QgPSBwb3N0Y3NzLnBhcnNlKCdhIHsgY29sb3I6IGJsYWNrIH0nKVxuICAgKiBjb25zdCBkZWNsID0gcm9vdC5maXJzdC5maXJzdFxuICAgKiBkZWNsLnZhbHVlIC8vPT4gJ2JsYWNrJ1xuICAgKi9cblxuICAvKipcbiAgICogQG1lbWJlcm9mIERlY2xhcmF0aW9uI1xuICAgKiBAbWVtYmVyIHtib29sZWFufSBpbXBvcnRhbnQgYHRydWVgIGlmIHRoZSBkZWNsYXJhdGlvblxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzIGFuICFpbXBvcnRhbnQgYW5ub3RhdGlvbi5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3Qgcm9vdCA9IHBvc3Rjc3MucGFyc2UoJ2EgeyBjb2xvcjogYmxhY2sgIWltcG9ydGFudDsgY29sb3I6IHJlZCB9JylcbiAgICogcm9vdC5maXJzdC5maXJzdC5pbXBvcnRhbnQgLy89PiB0cnVlXG4gICAqIHJvb3QuZmlyc3QubGFzdC5pbXBvcnRhbnQgIC8vPT4gdW5kZWZpbmVkXG4gICAqL1xuXG4gIC8qKlxuICAgKiBAbWVtYmVyb2YgRGVjbGFyYXRpb24jXG4gICAqIEBtZW1iZXIge29iamVjdH0gcmF3cyBJbmZvcm1hdGlvbiB0byBnZW5lcmF0ZSBieXRlLXRvLWJ5dGUgZXF1YWxcbiAgICogICAgICAgICAgICAgICAgICAgICAgIG5vZGUgc3RyaW5nIGFzIGl0IHdhcyBpbiB0aGUgb3JpZ2luIGlucHV0LlxuICAgKlxuICAgKiBFdmVyeSBwYXJzZXIgc2F2ZXMgaXRzIG93biBwcm9wZXJ0aWVzLFxuICAgKiBidXQgdGhlIGRlZmF1bHQgQ1NTIHBhcnNlciB1c2VzOlxuICAgKlxuICAgKiAqIGBiZWZvcmVgOiB0aGUgc3BhY2Ugc3ltYm9scyBiZWZvcmUgdGhlIG5vZGUuIEl0IGFsc28gc3RvcmVzIGAqYFxuICAgKiAgIGFuZCBgX2Agc3ltYm9scyBiZWZvcmUgdGhlIGRlY2xhcmF0aW9uIChJRSBoYWNrKS5cbiAgICogKiBgYmV0d2VlbmA6IHRoZSBzeW1ib2xzIGJldHdlZW4gdGhlIHByb3BlcnR5IGFuZCB2YWx1ZVxuICAgKiAgIGZvciBkZWNsYXJhdGlvbnMuXG4gICAqICogYGltcG9ydGFudGA6IHRoZSBjb250ZW50IG9mIHRoZSBpbXBvcnRhbnQgc3RhdGVtZW50LFxuICAgKiAgIGlmIGl0IGlzIG5vdCBqdXN0IGAhaW1wb3J0YW50YC5cbiAgICpcbiAgICogUG9zdENTUyBjbGVhbnMgZGVjbGFyYXRpb24gZnJvbSBjb21tZW50cyBhbmQgZXh0cmEgc3BhY2VzLFxuICAgKiBidXQgaXQgc3RvcmVzIG9yaWdpbiBjb250ZW50IGluIHJhd3MgcHJvcGVydGllcy5cbiAgICogQXMgc3VjaCwgaWYgeW91IGRvbuKAmXQgY2hhbmdlIGEgZGVjbGFyYXRpb27igJlzIHZhbHVlLFxuICAgKiBQb3N0Q1NTIHdpbGwgdXNlIHRoZSByYXcgdmFsdWUgd2l0aCBjb21tZW50cy5cbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogY29uc3Qgcm9vdCA9IHBvc3Rjc3MucGFyc2UoJ2Ege1xcbiAgY29sb3I6YmxhY2tcXG59JylcbiAgICogcm9vdC5maXJzdC5maXJzdC5yYXdzIC8vPT4geyBiZWZvcmU6ICdcXG4gICcsIGJldHdlZW46ICc6JyB9XG4gICAqL1xufVxuXG5leHBvcnQgZGVmYXVsdCBEZWNsYXJhdGlvblxuIl0sImZpbGUiOiJkZWNsYXJhdGlvbi5qcyJ9
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More