From 94ce815da4da5d7d952d5ece74af294566f572b3 Mon Sep 17 00:00:00 2001 From: Maxime Thirouin Date: Mon, 19 Oct 2015 08:43:21 +0200 Subject: [PATCH] Added: option `addDependencyTo` to make the integration with webpack more elegant (7.1.0) Ref https://github.com/postcss/postcss-loader/issues/31 --- .eslintrc | 35 ----------------------------------- CHANGELOG.md | 6 ++++++ LICENSE | 2 +- README.md | 37 +++++++++++++++++++++++++++---------- index.js | 25 +++++++++++++++++-------- package.json | 48 ++++++++++++++++++++++++++++++++++++++++++------ test/index.js | 48 +++++++++++++++++++++++++++++++++++++++--------- 7 files changed, 132 insertions(+), 69 deletions(-) delete mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index dd1794ed..00000000 --- a/.eslintrc +++ /dev/null @@ -1,35 +0,0 @@ ---- -ecmaFeatures: - modules: true - -env: - es6: true - browser: true - node: true - -rules: - indent: [2, 2] # 2 spaces indentation - max-len: [2, 80, 4] - quotes: [2, "double"] - semi: [2, "never"] - no-multiple-empty-lines: [2, {"max": 1}] - - brace-style: [2, "stroustrup"] - comma-dangle: [2, "always-multiline"] - comma-style: [2, "last"] - computed-property-spacing: [2, "never"] - object-curly-spacing: [2, "never"] - array-bracket-spacing: [2, "never"] - dot-location: [2, "property"] - - one-var: [2, "never"] - no-bitwise: [2] - - space-after-keywords: [2, "always"] - space-before-blocks: [2, "always"] - space-before-function-paren: [2, "never"] - space-in-parens: [2, "never"] - spaced-comment: [2, "always"] - - # this plugin need a refactoring... - no-use-before-define: 0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 374f0e8d..900d2de1 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 7.1.0 - 2015-10-19 + +- Added: option `addDependencyTo` to make the integration with webpack more +elegant +(ref [postcss-loader#31](https://github.com/postcss/postcss-loader/issues/31)) + # 7.0.0 - 2015-08-25 - Removed: compatibility with postcss v4.x diff --git a/LICENSE b/LICENSE index 13983fbf..8aad8d24 100755 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Maxime Thirouin, Jason Campbell & Kevin Mårtensson +Copyright (c) Maxime Thirouin, Jason Campbell & Kevin Mårtensson 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 diff --git a/README.md b/README.md index 184f064e..974d5057 100755 --- a/README.md +++ b/README.md @@ -3,7 +3,11 @@ > [PostCSS](https://github.com/postcss/postcss) plugin to transform `@import` rules by inlining content. This plugin can consume local files, node modules or bower packages. -To resolve path of an `@import` rule, it can look into root directory (by default `process.cwd()`), `node_modules` (Per [`package.json's style` attribute](http://stackoverflow.com/questions/32037150/style-field-in-package-json)), `web_modules`, `bower_components` or local modules. +To resolve path of an `@import` rule, it can look into root directory +(by default `process.cwd()`), `node_modules`, `web_modules`, `bower_components` +or local modules. +_When importing a module, it will looks for `index.css` or file referenced in +`package.json` in the `style` field._ You can also provide manually multiples paths where to look at. **Notes:** @@ -161,6 +165,24 @@ It's to optimize output and skip similar files like `normalize.css` for example. If this behavior is not what you want, just set this option to `false` to disable it. +#### `addDependencyTo` + +Type: `Function` +Default: null + +Allow to generate and call a callback that take one argument, the object from +which you need to call `addDependency` from. +Called whenever a file is imported, handy in a webpack workflow. +It's equivalent to `onImport` with the following code: + +```js +{ + onImport: function (files) { + files.forEach(this.addDependency) + }.bind(obj) // obj = the argument you should pass to `addDependencyTo()` +} +``` + #### Example with some options ```js @@ -178,16 +200,11 @@ var css = postcss() --- -## Contributing - -Work on a branch, install dev-dependencies, respect coding style & run tests before submitting a bug fix or a feature. +## CONTRIBUTING -```console -$ git clone https://github.com/postcss/postcss-import.git -$ git checkout -b patch-1 -$ npm install -$ npm test -``` +* ⇄ Pull requests and ★ Stars are always welcome. +* For bugs and feature requests, please create an issue. +* Pull requests must be accompanied by passing automated tests (`$ npm test`). ## [Changelog](CHANGELOG.md) diff --git a/index.js b/index.js index daf004fc..1c67d6ab 100755 --- a/index.js +++ b/index.js @@ -43,11 +43,12 @@ function AtImport(options) { // convert string to an array of a single element if (typeof options.path === "string") { - options.path = [options.path] + options.path = [ options.path ] } return function(styles, result) { - const opts = assign({}, options || {}) + var opts = assign({}, options || {}) + // auto add from option if possible if ( !opts.from && @@ -92,6 +93,14 @@ function AtImport(options) { function onParseEnd() { addIgnoredAtRulesOnTop(styles, state.ignoredAtRules) + if ( + typeof opts.addDependencyTo === "object" && + typeof opts.addDependencyTo.addDependency === "function" + ) { + Object.keys(state.importedFiles) + .forEach(opts.addDependencyTo.addDependency) + } + if (typeof opts.onImport === "function") { opts.onImport(Object.keys(state.importedFiles)) } @@ -132,7 +141,7 @@ function parseStyles( var imports = [] styles.walkAtRules("import", function checkAtRule(atRule) { if (atRule.nodes) { - result.warn(warnNodesMessage, {node: atRule}) + result.warn(warnNodesMessage, { node: atRule }) } if (options.glob && glob.hasMagic(atRule.params)) { imports = parseGlob(atRule, options, imports) @@ -268,7 +277,7 @@ function readAtImport( parsedAtImport.media = media // save - state.ignoredAtRules.push([atRule, parsedAtImport]) + state.ignoredAtRules.push([ atRule, parsedAtImport ]) // detach detach(atRule) @@ -350,7 +359,7 @@ function readImportedContent( ) if (fileContent.trim() === "") { - result.warn(resolvedFilename + " is empty", {node: atRule}) + result.warn(resolvedFilename + " is empty", { node: atRule }) detach(atRule) return resolvedPromise } @@ -440,7 +449,7 @@ function insertRules(atRule, parsedAtImport, newStyles) { // move nodes wrapper.nodes = newNodes - newNodes = [wrapper] + newNodes = [ wrapper ] } else if (newNodes && newNodes.length) { newNodes[0].raws.before = atRule.raws.before @@ -453,7 +462,7 @@ function insertRules(atRule, parsedAtImport, newStyles) { // replace atRule by imported nodes var nodes = atRule.parent.nodes - nodes.splice.apply(nodes, [nodes.indexOf(atRule), 0].concat(newNodes)) + nodes.splice.apply(nodes, [ nodes.indexOf(atRule), 0 ].concat(newNodes)) detach(atRule) } @@ -489,7 +498,7 @@ function resolveFilename(name, root, paths, source, resolver) { basedir: dir, moduleDirectory: moduleDirectories.concat(paths), paths: paths, - extensions: [".css"], + extensions: [ ".css" ], packageFilter: function processPackage(pkg) { pkg.main = pkg.style || "index.css" return pkg diff --git a/package.json b/package.json index 2c26be23..c16381e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postcss-import", - "version": "7.0.0", + "version": "7.1.0", "description": "PostCSS plugin to import CSS files", "keywords": [ "css", @@ -12,10 +12,7 @@ ], "author": "Maxime Thirouin", "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/postcss/postcss-import.git" - }, + "repository": "https://github.com/postcss/postcss-import.git", "files": [ "index.js" ], @@ -33,6 +30,45 @@ "tape": "^4.0.3" }, "scripts": { - "test": "eslint . && tape test" + "eslint": "eslint .", + "tape": "tape test", + "test": "npm run eslint && npm run tape" + }, + + "eslintConfig": { + "extends": "eslint:recommended", + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true + }, + "env": { + "es6": true, + "node": true + }, + "rules": { + "indent": [ 2, 2 ], + "max-len": [ 2, 80, 4 ], + "no-multiple-empty-lines": [ 2, { "max": 1 } ], + "quotes": [ 2, "double" ], + "semi": [ 2, "never" ], + "comma-dangle": [ 2, "always-multiline" ], + "comma-style": [ 2, "last" ], + "brace-style": [ 2, "stroustrup" ], + "dot-location": [ 2, "property" ], + "computed-property-spacing": [ 2, "never" ], + "object-curly-spacing": [ 2, "always" ], + "array-bracket-spacing": [ 2, "always" ], + "space-after-keywords": [ 2, "always" ], + "space-before-blocks": [ 2, "always" ], + "space-before-function-paren": [ 2, "never" ], + "space-in-parens": [ 2, "never" ], + "space-unary-ops": [ 2, { "words": true, "nonwords": false } ], + "spaced-comment": [ 2, "always" ], + + "one-var": [ 2, "never" ], + "no-bitwise": [ 2 ], + "prefer-const": [ 2 ] + } } + } diff --git a/test/index.js b/test/index.js index c1629fc1..5ea3e160 100755 --- a/test/index.js +++ b/test/index.js @@ -15,7 +15,7 @@ function read(name) { } function compareFixtures(t, name, msg, opts, postcssOpts) { - opts = assign({path: importsDir}, opts || {}) + opts = assign({ path: importsDir }, opts || {}) postcss(atImport(opts)) .process(read("fixtures/" + name), postcssOpts) .then(trimResultCss) @@ -96,14 +96,14 @@ test("@import", function(t) { "relative-to-source", "should not need `path` option if `source` option has been passed", null, - {from: "test/fixtures/relative-to-source.css"} + { from: "test/fixtures/relative-to-source.css" } ) compareFixtures( t, "modules", "should be able to consume npm package or local modules", - {root: __dirname} + { root: __dirname } ) var base = "@import url(http://)" @@ -138,7 +138,7 @@ test("@import error output", function(t) { var file = importsDir + "/import-missing.css" postcss() .use(atImport()) - .process(fs.readFileSync(file), {from: file}) + .process(fs.readFileSync(file), { from: file }) .catch(function(error) { t.throws( function() { @@ -157,8 +157,8 @@ test("@import error output", function(t) { test("@import glob pattern matches no files", function(t) { var file = importsDir + "/glob-missing.css" postcss() - .use(atImport({glob: true})) - .process(fs.readFileSync(file), {from: file}) + .use(atImport({ glob: true })) + .process(fs.readFileSync(file), { from: file }) .then(trimResultCss) .then(function(css) { t.equal( @@ -219,9 +219,39 @@ test("@import callback", function(t) { .then(trimResultCss) }) +test("@import callback (webpack)", function(t) { + var files = [] + var webpackMock = { + addDependency: (file) => files.push(file), + } + + postcss() + .use(atImport({ + path: importsDir, + addDependencyTo: webpackMock, + })) + .process(read("fixtures/recursive"), { + from: "./test/fixtures/recursive.css", + }) + .then(trimResultCss) + .then(() => { + t.deepEqual( + files, + [ + path.join(__dirname, "fixtures", "recursive.css"), + path.join(__dirname, "fixtures", "imports", "foo-recursive.css"), + path.join(__dirname, "fixtures", "imports", "bar.css"), + ], + "should have a callback shortcut for webpack" + ) + + t.end() + }) +}) + test("import relative files using path option only", function(t) { postcss() - .use(atImport({path: "test/fixtures/imports/relative"})) + .use(atImport({ path: "test/fixtures/imports/relative" })) .process(read("fixtures/imports/relative/import")) .then(trimResultCss) .then(function(css) { @@ -262,7 +292,7 @@ test("@import custom resolve", function(t) { var resolve = require("resolve") var sassResolve = function(file, opts) { opts = opts || {} - opts.extensions = [".scss", ".css"] + opts.extensions = [ ".scss", ".css" ] opts.packageFilter = function(pkg) { pkg.main = pkg.sass || pkg.style || "index" return pkg @@ -273,7 +303,7 @@ test("@import custom resolve", function(t) { t, "custom-resolve-modules", "should be able to consume modules in the custom-resolve way", - {root: __dirname, path: importsDir, resolve: sassResolve} + { root: __dirname, path: importsDir, resolve: sassResolve } ) t.end()