Skip to content

Commit

Permalink
Merge pull request #1 from css-modules/chore-deps-update
Browse files Browse the repository at this point in the history
chore(deps): update
  • Loading branch information
evilebottnawi authored Nov 23, 2018
2 parents cf3b45b + e995f11 commit 1383b62
Show file tree
Hide file tree
Showing 6 changed files with 3,029 additions and 172 deletions.
11 changes: 11 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"parserOptions": {
"ecmaVersion": 2018
},
"env": {
"node": true
},
"rules": {
"quotes": [2, "single"]
}
}
11 changes: 7 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
language: node_js
node_js:
- "4"
- "6"
- "node"
- "8"
- "10"
- "11"
script: npm run travis

before_install:
- '[ "${TRAVIS_NODE_VERSION}" != "0.10" ] || npm install -g npm'
after_success:
- cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
- cat ./coverage/coverage.json | node_modules/codecov.io/bin/codecov.io.js
- rm -rf ./coverage
42 changes: 18 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
{
"name": "postcss-modules-values",
"version": "1.3.1",
"version": "2.0.0",
"description": "PostCSS plugin for CSS Modules to pass arbitrary values between your module files",
"main": "lib/index.js",
"main": "src/index.js",
"files": [
"src"
],
"scripts": {
"lint": "standard src test",
"build": "babel --out-dir lib src",
"lint": "eslint src test",
"pretest": "yarn lint",
"test": "mocha",
"autotest": "chokidar src test -c 'npm test'",
"test": "mocha --compilers js:babel-core/register",
"posttest": "npm run lint && npm run build",
"travis": "npm run test",
"prepublish": "npm run build"
"cover": "nyc mocha",
"travis": "yarn lint && yarn cover",
"prepublish": "yarn test"
},
"repository": {
"type": "git",
Expand All @@ -28,24 +31,15 @@
},
"homepage": "https://github.com/css-modules/postcss-modules-values#readme",
"devDependencies": {
"babel-cli": "^6.5.2",
"babel-core": "^6.5.2",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-preset-es2015": "^6.3.13",
"chokidar": "^1.2.0",
"mocha": "^3.0.2",
"standard": "^8.4.0"
"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": "^6.0.1"
},
"babel": {
"presets": [
"es2015"
],
"plugins": [
"add-module-exports"
]
"postcss": "^7.0.6"
}
}
191 changes: 105 additions & 86 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,100 +1,119 @@
import postcss from 'postcss'
import replaceSymbols, {replaceAll} from 'icss-replace-symbols'
'use strict';

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++}`)
const postcss = require('postcss');
const ICSSReplaceSymbols = require('icss-replace-symbols');
const replaceSymbols = require('icss-replace-symbols');

export default postcss.plugin('postcss-modules-values', () => (css, result) => {
let importAliases = []
let definitions = {}
const matchImports = /^(.+?|\([\s\S]+?\))\s+from\s+("[^"]*"|'[^']*'|[\w-]+)$/;
const matchValueDefinition = /(?:\s+|^)([\w-]+):?\s+(.+?)\s*$/g;
const matchImport = /^([\w-]+)(?:\s+as\s+([\w-]+))?/;

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] = replaceAll(definitions, value)
atRule.remove()
}
}
let options = {};
let importIndex = 0;
let createImportedName =
(options && options.createImportedName) ||
((importName /*, path*/) =>
`i__const_${importName.replace(/\W/g, '_')}_${importIndex++}`);

const addImport = atRule => {
let 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]
let imports = aliases.replace(/^\(\s*([\s\S]+)\s*\)$/, '$1').split(/\s*,\s*/).map(alias => {
let tokens = matchImport.exec(alias)
if (tokens) {
let [/*match*/, theirName, myName = theirName] = tokens
let importedName = createImportedName(myName)
definitions[myName] = importedName
return { theirName, importedName }
} else {
throw new Error(`@import statement "${alias}" is invalid!`)
}
})
importAliases.push({ path, imports })
atRule.remove()
}
}
module.exports = postcss.plugin(
'postcss-modules-values',
() => (css, result) => {
const importAliases = [];
const definitions = {};

/* 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)
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();
}
};

addDefinition(atRule)
}
})
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();
}
};

/* We want to export anything defined by now, but don't add it to the CSS yet or
/* 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 */
let exportDeclarations = Object.keys(definitions).map(key => postcss.decl({
value: definitions[key],
prop: key,
raws: { before: "\n " }
}))
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
/* If we have no definitions, don't continue */
if (!Object.keys(definitions).length) {
return;
}

/* Perform replacements */
replaceSymbols(css, definitions)
/* Perform replacements */
ICSSReplaceSymbols.default(css, definitions);

/* Add export rules if any */
if (exportDeclarations.length > 0) {
let exportRule = postcss.rule({
selector: `:export`,
raws: { after: "\n" }
})
exportRule.append(exportDeclarations)
css.prepend(exportRule)
}
/* 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 }) => {
let importRule = postcss.rule({
selector: `:import(${path})`,
raws: { after: "\n" }
})
imports.forEach(({ theirName, importedName }) => {
importRule.append({
value: theirName,
prop: importedName,
raws: { before: "\n " }
})
})
/* 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)
})
})
css.prepend(importRule);
});
}
);
Loading

0 comments on commit 1383b62

Please sign in to comment.