Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy css-modules-loader-core sources into the repo #108

Merged
merged 7 commits into from
Jun 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ sudo: false
language: node_js
node_js:
- node
- 11
- 12
- 10
- 8
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## 3.0.0

### Changed

- Dropped `css-modules-loader-core` dependency
- [Upgraded all the dependencies](https://github.com/css-modules/postcss-modules/pull/108)

### Breaking changes

- Dropped support for unsupported Node versions. Supported versions are 10, 12 and 14+ https://nodejs.org/en/about/releases/

## 2.0.0

### Added
Expand Down
24 changes: 14 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,29 @@
"url": "https://github.com/css-modules/postcss-modules.git"
},
"dependencies": {
"css-modules-loader-core": "^1.1.0",
"generic-names": "^2.0.1",
"icss-replace-symbols": "^1.1.0",
"lodash.camelcase": "^4.3.0",
"postcss": "^7.0.1",
"postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.2",
"postcss-modules-scope": "^2.2.0",
"postcss-modules-values": "^3.0.0",
"string-hash": "^1.1.1"
},
"devDependencies": {
"autoprefixer": "^9.6.1",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.3",
"babel-eslint": "^10.1.0",
"babel-preset-env": "^1.7.0",
"eslint": "^6.4.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-jest": "^22.17.0",
"husky": "^3.0.5",
"jest": "^24.9.0",
"lint-staged": "^9.2.5",
"prettier": "^1.18.2"
"eslint": "^7.3.1",
"eslint-plugin-import": "^2.21.2",
"eslint-plugin-jest": "^23.17.0",
"husky": "^4.2.5",
"jest": "^26.0.1",
"lint-staged": "^10.2.11",
"prettier": "^2.0.5"
},
"scripts": {
"pretest": "$(npm bin)/eslint src test",
Expand Down
10 changes: 5 additions & 5 deletions src/behaviours.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Core from "css-modules-loader-core";
import Core from "./css-loader-core";

export const behaviours = {
LOCAL: "local",
GLOBAL: "global"
GLOBAL: "global",
};

export function getDefaultPlugins(behaviour, generateScopedName) {
Expand All @@ -13,10 +13,10 @@ export function getDefaultPlugins(behaviour, generateScopedName) {
Core.values,
Core.localByDefault,
Core.extractImports,
scope
scope,
],

[behaviours.GLOBAL]: [Core.values, Core.extractImports, scope]
[behaviours.GLOBAL]: [Core.values, Core.extractImports, scope],
};

return plugins[behaviour];
Expand All @@ -25,7 +25,7 @@ export function getDefaultPlugins(behaviour, generateScopedName) {
export function isValidBehaviour(behaviour) {
return (
Object.keys(behaviours)
.map(key => behaviours[key])
.map((key) => behaviours[key])
.indexOf(behaviour) > -1
);
}
36 changes: 36 additions & 0 deletions src/css-loader-core/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copied from https://github.com/css-modules/css-modules-loader-core

import postcss from "postcss";
import localByDefault from "postcss-modules-local-by-default";
import extractImports from "postcss-modules-extract-imports";
import scope from "postcss-modules-scope";
import values from "postcss-modules-values";

import Parser from "./parser";

export default class Core {
constructor(plugins) {
this.plugins = plugins || Core.defaultPlugins;
}

load(sourceString, sourcePath, trace, pathFetcher) {
let parser = new Parser(pathFetcher, trace);

return postcss(this.plugins.concat([parser.plugin]))
.process(sourceString, { from: "/" + sourcePath })
.then((result) => {
return {
injectableSource: result.css,
exportTokens: parser.exportTokens,
};
});
}
}

// These four plugins are aliased under this package for simplicity.
Core.values = values;
Core.localByDefault = localByDefault;
Core.extractImports = extractImports;
Core.scope = scope;

Core.defaultPlugins = [values, localByDefault, extractImports, scope];
91 changes: 91 additions & 0 deletions src/css-loader-core/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Copied from https://github.com/css-modules/css-modules-loader-core

import Core from "./index.js";
import fs from "fs";
import path from "path";

// Sorts dependencies in the following way:
// AAA comes before AA and A
// AB comes after AA and before A
// All Bs come after all As
// This ensures that the files are always returned in the following order:
// - In the order they were required, except
// - After all their dependencies
const traceKeySorter = (a, b) => {
if (a.length < b.length) {
return a < b.substring(0, a.length) ? -1 : 1;
} else if (a.length > b.length) {
return a.substring(0, b.length) <= b ? -1 : 1;
} else {
return a < b ? -1 : 1;
}
};

export default class FileSystemLoader {
constructor(root, plugins) {
this.root = root;
this.sources = {};
this.traces = {};
this.importNr = 0;
this.core = new Core(plugins);
this.tokensByFile = {};
}

fetch(_newPath, relativeTo, _trace) {
let newPath = _newPath.replace(/^["']|["']$/g, ""),
trace = _trace || String.fromCharCode(this.importNr++);
return new Promise((resolve, reject) => {
let relativeDir = path.dirname(relativeTo),
rootRelativePath = path.resolve(relativeDir, newPath),
fileRelativePath = path.resolve(
path.join(this.root, relativeDir),
newPath
);

// if the path is not relative or absolute, try to resolve it in node_modules
if (newPath[0] !== "." && newPath[0] !== "/") {
try {
fileRelativePath = require.resolve(newPath);
} catch (e) {
// noop
}
}

const tokens = this.tokensByFile[fileRelativePath];
if (tokens) {
return resolve(tokens);
}

fs.readFile(fileRelativePath, "utf-8", (err, source) => {
if (err) reject(err);
this.core
.load(source, rootRelativePath, trace, this.fetch.bind(this))
.then(({ injectableSource, exportTokens }) => {
this.sources[fileRelativePath] = injectableSource;
this.traces[trace] = fileRelativePath;
this.tokensByFile[fileRelativePath] = exportTokens;
resolve(exportTokens);
}, reject);
});
});
}

get finalSource() {
const traces = this.traces;
const sources = this.sources;
let written = new Set();

return Object.keys(traces)
.sort(traceKeySorter)
.map((key) => {
const filename = traces[key];
if (written.has(filename)) {
return null;
}
written.add(filename);

return sources[filename];
})
.join("");
}
}
74 changes: 74 additions & 0 deletions src/css-loader-core/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copied from https://github.com/css-modules/css-modules-loader-core

const importRegexp = /^:import\((.+)\)$/;
import replaceSymbols from "icss-replace-symbols";

export default class Parser {
constructor(pathFetcher, trace) {
this.pathFetcher = pathFetcher;
this.plugin = this.plugin.bind(this);
this.exportTokens = {};
this.translations = {};
this.trace = trace;
}

plugin(css) {
return Promise.all(this.fetchAllImports(css))
.then(() => this.linkImportedSymbols(css))
.then(() => this.extractExports(css));
}

fetchAllImports(css) {
let imports = [];
css.each((node) => {
if (node.type == "rule" && node.selector.match(importRegexp)) {
imports.push(
this.fetchImport(node, css.source.input.from, imports.length)
);
}
});
return imports;
}

linkImportedSymbols(css) {
replaceSymbols(css, this.translations);
}

extractExports(css) {
css.each((node) => {
if (node.type == "rule" && node.selector == ":export")
this.handleExport(node);
});
}

handleExport(exportNode) {
exportNode.each((decl) => {
if (decl.type == "decl") {
Object.keys(this.translations).forEach((translation) => {
decl.value = decl.value.replace(
translation,
this.translations[translation]
);
});
this.exportTokens[decl.prop] = decl.value;
}
});
exportNode.remove();
}

fetchImport(importNode, relativeTo, depNr) {
let file = importNode.selector.match(importRegexp)[1],
depTrace = this.trace + String.fromCharCode(depNr);
return this.pathFetcher(file, relativeTo, depTrace).then(
(exports) => {
importNode.each((decl) => {
if (decl.type == "decl") {
this.translations[decl.prop] = exports[decl.value];
}
});
importNode.remove();
},
(err) => console.log(err)
);
}
}
4 changes: 1 addition & 3 deletions src/generateScopedName.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import stringHash from "string-hash";
export default function generateScopedName(name, filename, css) {
const i = css.indexOf(`.${name}`);
const lineNumber = css.substr(0, i).split(/[\r\n]/).length;
const hash = stringHash(css)
.toString(36)
.substr(0, 5);
const hash = stringHash(css).toString(36).substr(0, 5);

return `_${name}_${hash}_${lineNumber}`;
}
14 changes: 8 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import postcss from "postcss";
import camelCase from "lodash.camelcase";
import Parser from "css-modules-loader-core/lib/parser";
import FileSystemLoader from "css-modules-loader-core/lib/file-system-loader";
import genericNames from "generic-names";

import Parser from "./css-loader-core/parser";
import FileSystemLoader from "./css-loader-core/loader";

import generateScopedName from "./generateScopedName";
import saveJSON from "./saveJSON";
import { getDefaultPlugins, isValidBehaviour, behaviours } from "./behaviours";
Expand All @@ -23,7 +25,7 @@ function getScopedNameGenerator(opts) {
if (typeof scopedNameGenerator === "function") return scopedNameGenerator;
return genericNames(scopedNameGenerator, {
context: process.cwd(),
hashPrefix: opts.hashPrefix
hashPrefix: opts.hashPrefix,
});
}

Expand All @@ -35,7 +37,7 @@ function getLoader(opts, plugins) {
}

function isGlobalModule(globalModules, inputFile) {
return globalModules.some(regex => inputFile.match(regex));
return globalModules.some((regex) => inputFile.match(regex));
}

function getDefaultPluginsList(opts, inputFile) {
Expand Down Expand Up @@ -72,7 +74,7 @@ module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
const parser = new Parser(loader.fetch.bind(loader));

await postcss([...plugins, parser.plugin]).process(css, {
from: inputFile
from: inputFile,
});

const out = loader.finalSource;
Expand Down Expand Up @@ -111,7 +113,7 @@ module.exports = postcss.plugin(PLUGIN_NAME, (opts = {}) => {
result.messages.push({
type: "export",
plugin: "postcss-modules",
exportTokens: parser.exportTokens
exportTokens: parser.exportTokens,
});

// getJSON may return a promise
Expand Down
6 changes: 2 additions & 4 deletions src/saveJSON.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ import { writeFile } from "fs";

export default function saveJSON(cssFile, json) {
return new Promise((resolve, reject) => {
writeFile(
`${cssFile}.json`,
JSON.stringify(json),
e => (e ? reject(e) : resolve(json))
writeFile(`${cssFile}.json`, JSON.stringify(json), (e) =>
e ? reject(e) : resolve(json)
);
});
}
Loading