Socket
Socket
Sign inDemoInstall

css-loader

Package Overview
Dependencies
70
Maintainers
1
Versions
152
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.14.5 to 0.15.0

lib/getImportPrefix.js

191

lib/loader.js

@@ -6,8 +6,7 @@ /*

var path = require("path");
var parseSource = require("./parseSource");
var ReplaceMany = require("./ReplaceMany");
var loaderUtils = require("loader-utils");
var SourceListMap = require("source-list-map").SourceListMap;
var CleanCSS = require("clean-css");
var processCss = require("./processCss");
var getImportPrefix = require("./getImportPrefix");
module.exports = function(content, map) {

@@ -17,5 +16,2 @@ if(this.cacheable) this.cacheable();

var root = query.root;
var forceMinimize = query.minimize;
var importLoaders = parseInt(query.importLoaders, 10) || 0;
var minimize = typeof forceMinimize !== "undefined" ? !!forceMinimize : (this && this.minimize);
var moduleMode = query.module;

@@ -27,96 +23,49 @@

var result = [];
var result = processCss(content, map, {
mode: moduleMode ? "local" : "global",
from: loaderUtils.getRemainingRequest(this),
to: loaderUtils.getCurrentRequest(this),
query: query,
minimize: this.minimize,
loaderContext: this
});
var cssAsString = JSON.stringify(result.source);
// for importing CSS
var loadersRequest = this.loaders.slice(
this.loaderIndex,
this.loaderIndex + 1 + importLoaders
).map(function(x) { return x.request; }).join("!");
var importUrlPrefix = "-!" + loadersRequest + "!";
var importUrlPrefix = getImportPrefix(this, query);
var stuff = parseSource(content);
var replacer = new ReplaceMany();
// store already imported files
var importedUrls = [];
// add @imports to result
stuff.imports.forEach(function(imp) {
replacer.replace(imp.start, imp.length, "");
var alreadyImported = {};
var importJs = result.importItems.filter(function(imp) {
if(!imp.mediaQuery) {
if(alreadyImported[imp.url])
return false;
alreadyImported[imp.url] = true;
}
return true;
}).map(function(imp) {
if(!loaderUtils.isUrlRequest(imp.url, root)) {
result.push("exports.push([module.id, " +
return "exports.push([module.id, " +
JSON.stringify("@import url(" + imp.url + ");") + ", " +
JSON.stringify(imp.mediaQuery) + "]);");
JSON.stringify(imp.mediaQuery) + "]);";
} else {
var importUrl = importUrlPrefix +
(moduleMode ? imp.url : loaderUtils.urlToRequest(imp.url));
result.push("exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), " + JSON.stringify(imp.mediaQuery) + ");");
if(!imp.mediaQuery)
importedUrls.push(importUrl);
var importUrl = importUrlPrefix + imp.url;
return "exports.i(require(" + loaderUtils.stringifyRequest(this, importUrl) + "), " + JSON.stringify(imp.mediaQuery) + ");";
}
}, this);
}).join("\n");
// replace url(...)
if(query.url !== false) {
stuff.urls.forEach(function(url, idx) {
replacer.replace(url.start, url.length, "__CSSLOADERURL_" + idx + "__");
});
function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ").locals" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}
// replace :local()
var locals = {};
var localExtends = {};
require("./processLocals").call(this, stuff.selectors, query, replacer, locals, localExtends);
// remove stuff
stuff.remove.forEach(function(rem) {
replacer.replace(rem.start, rem.length, "");
});
// pass errors from parser
if(this.emitError) {
stuff.errors.forEach(function(err) {
this.emitError(err);
}, this);
}
// generate the locals
var localsData = require("./generateLocals").call(this, locals, localExtends, importedUrls, importUrlPrefix, result, ".locals");
if(localsData) {
result.push("exports.locals = " + localsData + ";");
}
// transform the CSS
var cssContent = replacer.run(content);
// minimize CSS
if(minimize) {
var options = Object.create(query);
if(query.sourceMap && map) {
options.sourceMap = map;
}
var minimizeResult = new CleanCSS(options).minify(cssContent);
map = minimizeResult.sourceMap;
cssContent = minimizeResult.styles;
if(typeof map !== "string")
map = JSON.stringify(map);
}
function toEmbStr(str) {
return JSON.stringify(str).replace(/^"|"$/g, "");
}
// replace url(...) in the generated code
var css = JSON.stringify(cssContent);
var urlRegExp = /__CSSLOADERURL_[0-9]+__/g;
css = css.replace(urlRegExp, function(str) {
var match = /^__CSSLOADERURL_([0-9]+)__$/.exec(str);
if(!match) return str;
var idx = parseInt(match[1], 10);
if(!stuff.urls[idx]) return str;
var urlItem = stuff.urls[idx];
cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this)).replace(result.urlItemRegExpG, function(item) {
var match = result.urlItemRegExp.exec(item);
var idx = +match[1];
var urlItem = result.urlItems[idx];
var url = urlItem.url;
if(!loaderUtils.isUrlRequest(url, root))
return toEmbStr(urlItem.raw);
idx = url.indexOf("?#");

@@ -128,34 +77,37 @@ if(idx < 0) idx = url.indexOf("#");

urlRequest = url.substr(0, idx);
if(!moduleMode) urlRequest = loaderUtils.urlToRequest(urlRequest, root);
return "\"+require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")+\"" + url.substr(idx);
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"" +
url.substr(idx);
}
urlRequest = url;
if(!moduleMode) urlRequest = loaderUtils.urlToRequest(url, root);
return "\"+require(" + loaderUtils.stringifyRequest(this, urlRequest) + ")+\"";
return "\" + require(" + loaderUtils.stringifyRequest(this, urlRequest) + ") + \"";
}.bind(this));
// add a SourceMap
if(query.sourceMap && !minimize) {
var cssRequest = loaderUtils.getRemainingRequest(this);
var request = loaderUtils.getCurrentRequest(this);
if(!map) {
var sourceMap = new SourceListMap();
sourceMap.add(content, cssRequest, content);
map = sourceMap.toStringWithSourceMap({
file: request
}).map;
if(map.sources) {
map.sources = map.sources.map(function(source) {
var p = path.relative(query.context || this.options.context, source).replace(/\\/g, "/");
if(p.indexOf("../") !== 0)
p = "./" + p;
return "/" + p;
}, this);
map.sourceRoot = "webpack://";
}
map = JSON.stringify(map);
var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "exports.locals = {\n" + exportJs + "\n};";
}
var moduleJs;
if(query.sourceMap && result.map) {
// add a SourceMap
map = result.map;
if(map.sources) {
map.sources = map.sources.map(function(source) {
var p = path.relative(query.context || this.options.context, source).replace(/\\/g, "/");
if(p.indexOf("../") !== 0)
p = "./" + p;
return "/" + p;
}, this);
map.sourceRoot = "webpack://";
}
result.push("exports.push([module.id, " + css + ", \"\", " + map + "]);");
map = JSON.stringify(map);
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\", " + map + "]);";
} else {
result.push("exports.push([module.id, " + css + ", \"\"]);");
moduleJs = "exports.push([module.id, " + cssAsString + ", \"\"]);";
}

@@ -165,3 +117,8 @@

return "exports = module.exports = require(" + loaderUtils.stringifyRequest(this, require.resolve("./css-base.js")) + ")();\n" +
result.join("\n");
"// imports\n" +
importJs + "\n\n" +
"// module\n" +
moduleJs + "\n\n" +
"// exports\n" +
exportJs;
};

@@ -6,28 +6,41 @@ /*

var loaderUtils = require("loader-utils");
var parseSource = require("./parseSource");
var processCss = require("./processCss");
var getImportPrefix = require("./getImportPrefix");
module.exports = function(content) {
if(this.cacheable) this.cacheable();
var query = loaderUtils.parseQuery(this.query);
var importLoaders = parseInt(query.importLoaders, 10) || 0;
var moduleMode = query.module;
var result = processCss(content, null, {
mode: moduleMode ? "local" : "global",
query: query,
minimize: this.minimize,
loaderContext: this
});
// for importing CSS
var loadersRequest = this.loaders.slice(
this.loaderIndex,
this.loaderIndex + 1 + importLoaders
).map(function(x) { return x.request; }).join("!");
var importUrlPrefix = "-!" + loadersRequest + "!";
var importUrlPrefix = getImportPrefix(this, query);
var stuff = parseSource(content);
function importItemMatcher(item) {
var match = result.importItemRegExp.exec(item);
var idx = +match[1];
var importItem = result.importItems[idx];
var importUrl = importUrlPrefix + importItem.url;
return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ")" +
"[" + JSON.stringify(importItem.export) + "] + \"";
}
var locals = {};
var localExtends = {};
require("./processLocals").call(this, stuff.selectors, query, null, locals, localExtends);
var exportJs = "";
if(Object.keys(result.exports).length > 0) {
exportJs = Object.keys(result.exports).map(function(key) {
var valueAsString = JSON.stringify(result.exports[key]);
valueAsString = valueAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));
return "\t" + JSON.stringify(key) + ": " + valueAsString;
}.bind(this)).join(",\n");
exportJs = "module.exports = {\n" + exportJs + "\n};";
}
// generate the locals
var localsData = require("./generateLocals").call(this, locals, localExtends, null, importUrlPrefix, null, "");
return "module.exports = " + localsData + ";";
return exportJs;
};
{
"name": "css-loader",
"version": "0.14.5",
"version": "0.15.0",
"author": "Tobias Koppers @sokra",
"description": "css loader module for webpack",
"dependencies": {
"clean-css": "^3.1.9",
"fastparse": "^1.1.1",
"css-selector-tokenizer": "^0.5.1",
"cssnano": "^1.4.2",
"loader-utils": "~0.2.2",
"postcss": "^4.1.11",
"postcss-modules-extract-imports": "0.0.5",
"postcss-modules-local-by-default": "0.0.10",
"postcss-modules-scope": "0.0.7",
"source-list-map": "^0.1.4"

@@ -17,3 +21,3 @@ },

"mocha": "^2.2.4",
"should": "^5.2.0"
"should": "^7.0.1"
},

@@ -20,0 +24,0 @@ "scripts": {

@@ -20,3 +20,3 @@ # css loader for webpack

To be compatible with existing css files:
To be compatible with existing css files (if not in CSS Module mode):
* `url(image.png)` => `require("./image.png")`

@@ -62,2 +62,4 @@ * `url(~module/image.png)` => `require("module/image.png")`

Using 'Root-relative' urls is not recommended. You should only use it for legacy CSS files.
### Local scope

@@ -102,2 +104,7 @@

`url(...)` URLs in block scoped (`:local .abc`) rules behave like requests in modules:
* `./file.png` instead of `file.png`
* `module/file.png` instead of `~module/file.png`
You can use `:local(#someId)`, but this is not recommended. Use classes instead of ids.

@@ -107,3 +114,3 @@

Note: For prerendering with extract-text-webpack-plugin you should use `css-loader/locals` instead of `style-loader!css-loader` in the prerendering bundle. It doesn't embed CSS but only exports the identifier mappings.
Note: For prerendering with extract-text-webpack-plugin you should use `css-loader/locals` instead of `style-loader!css-loader` **in the prerendering bundle**. It doesn't embed CSS but only exports the identifier mappings.

@@ -114,15 +121,12 @@ ### Module mode

See [CSS Modules](https://github.com/css-modules/css-modules).
The query parameter `module` enables **CSS Module** mode. (`css-loader?module`)
* Local scoped by default.
* `url(...)` URLs behave like requests in modules:
* `./file.png` instead of `file.png`
* `module/file.png` instead of `~module/file.png`
This enables Local scoped CSS by default. (You can leave it with `:global(...)` or `:global` for selectors and/or rules.)
Thanks to [@markdalgleish](https://github.com/markdalgleish) for prior work on this topic.
### Composing CSS classes
### Inheriting
When declaring a local class name you can compose a local class from another local class name.
When declaring a local class name you can inherit from another local class name.
``` css

@@ -135,3 +139,3 @@ :local(.className) {

:local(.subClass) {
extends: className;
composes: className;
background: blue;

@@ -169,3 +173,3 @@ }

:local(.continueButton) {
extends: button from "library/button.css";
composes: button from "library/button.css";
background: red;

@@ -177,3 +181,3 @@ }

:local(.nameEdit) {
extends: edit highlight from "./edit.css";
composes: edit highlight from "./edit.css";
background: red;

@@ -183,10 +187,9 @@ }

To import from multiple modules use multiple `extends:` rules. You can also use `url(...)` to specify the module (it behave a bit different).
To import from multiple modules use multiple `composes:` rules.
``` css
:local(.className) {
extends: edit hightlight from "./edit.css";
extends: button from url("button.css");
/* equal to 'extends: button from "./button.css";' */
extends: classFromThisModule;
composes: edit hightlight from "./edit.css";
composes: button from "module/button.css";
composes: classFromThisModule;
background: red;

@@ -204,2 +207,4 @@ }

They are not enabled by default because they expose a runtime overhead and increase in bundle size (JS SourceMap do not). In addition to that relative paths are buggy and you need to use an absolute public path which include the server url.
### importing and chained loaders

@@ -223,2 +228,4 @@

This may change in the future, when the module system (i. e. webpack) supports loader matching by origin.
### Minification

@@ -225,0 +232,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc