Skip to content

Commit

Permalink
Merge branch 'v9-dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanZim committed Dec 3, 2016
2 parents 49cf9be + 7124d43 commit 7d9099c
Show file tree
Hide file tree
Showing 28 changed files with 251 additions and 121 deletions.
34 changes: 13 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,23 +126,6 @@ Default: `[]`

A string or an array of paths in where to look for files.

#### `transform`

Type: `Function`
Default: `null`

A function to transform the content of imported files. Take one argument (file
content) and should return the modified content or a resolved promise with it.
`undefined` result will be skipped.

```js
transform: function(css) {
return postcss([somePlugin]).process(css).then(function(result) {
return result.css;
});
}
```

#### `plugins`

Type: `Array`
Expand All @@ -163,10 +146,12 @@ files).
Type: `Function`
Default: `null`

You can overwrite the default path resolving way by setting this option.
This function gets `(id, basedir, importOptions)` arguments and returns full
path, array of paths or promise resolving paths.
You can use [resolve](https://github.com/substack/node-resolve) for that.
You can provide a custom path resolver with this option. This function gets
`(id, basedir, importOptions)` arguments and should return a path, an array of
paths or a promise resolving to the path(s). If you do not return an absolute
path, your path will be resolved to an absolute path using the default
resolver.
You can use [resolve](https://github.com/substack/node-resolve) for this.

#### `load`

Expand Down Expand Up @@ -230,6 +215,13 @@ postcss()
})
```

### jspm Usage

postcss-import can `@import` [jspm](http://jspm.io) dependencies if
[`pkg-resolve`](https://www.npmjs.com/package/pkg-resolve) is installed by the
user. Run `npm install pkg-resolve` to install it. postcss-import should then be
able to import from jspm dependencies without further configuration.

## `dependency` Message Support

`postcss-import` adds a message to `result.messages` for each `@import`. Messages are in the following format:
Expand Down
43 changes: 26 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var postcss = require("postcss")
var joinMedia = require("./lib/join-media")
var resolveId = require("./lib/resolve-id")
var loadContent = require("./lib/load-content")
var processContent = require("./lib/process-content")
var parseStatements = require("./lib/parse-statements")
var promiseEach = require("promise-each")

Expand Down Expand Up @@ -62,6 +63,14 @@ function AtImport(options) {
typeof options.addDependencyTo === "object" &&
typeof options.addDependencyTo.addDependency === "function"
) {
console.warn([
"addDependencyTo is deprecated in favor of",
"result.messages.dependency; postcss-loader >= v1.0.0 will",
"automatically add your imported files to webpack's file watcher.",
"For more information, see",
"https://github.com/postcss/postcss-import\
#dependency-message-support",
].join("\n"))
Object.keys(state.importedFiles)
.forEach(options.addDependencyTo.addDependency)
}
Expand Down Expand Up @@ -227,11 +236,18 @@ function resolveImportId(
: options.root

return Promise.resolve(options.resolve(stmt.uri, base, options))
.then(function(resolved) {
if (!Array.isArray(resolved)) {
resolved = [ resolved ]
.then(function(paths) {
if (!Array.isArray(paths)) {
paths = [ paths ]
}

return Promise.all(paths.map(function(file) {
// Ensure that each path is absolute:
if (!path.isAbsolute(file)) return resolveId(file, base, options)
return file
}))
})
.then(function(resolved) {
// Add dependency messages:
resolved.forEach(function(file) {
result.messages.push({
Expand Down Expand Up @@ -261,6 +277,7 @@ function resolveImportId(
}, [])
})
.catch(function(err) {
if (err.message.indexOf("Failed to find") !== -1) throw err
result.warn(err.message, { node: atRule })
})
}
Expand Down Expand Up @@ -291,15 +308,6 @@ function loadImportContent(
}

return Promise.resolve(options.load(filename, options))
.then(function(content) {
if (typeof options.transform !== "function") {
return content
}
return Promise.resolve(options.transform(content, filename, options))
.then(function(transformed) {
return typeof transformed === "string" ? transformed : content
})
})
.then(function(content) {
if (content.trim() === "") {
result.warn(filename + " is empty", { node: atRule })
Expand All @@ -314,11 +322,12 @@ function loadImportContent(
return
}

return postcss(options.plugins).process(content, {
from: filename,
syntax: result.opts.syntax,
parser: result.opts.parser,
})
return processContent(
result,
content,
filename,
options
)
.then(function(importedResult) {
var styles = importedResult.root
result.messages = result.messages.concat(importedResult.messages)
Expand Down
61 changes: 61 additions & 0 deletions lib/process-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
var path = require("path")
var postcss = require("postcss")
var sugarss

module.exports = function processContent(
result,
content,
filename,
options
) {
var plugins = options.plugins
var ext = path.extname(filename)

var parserList = []

// SugarSS support:
if (ext === ".sss") {
if (!sugarss) {
try {
sugarss = require("sugarss")
}
catch (e) {
// Ignore
}
}
if (sugarss) return runPostcss(content, filename, plugins, [ sugarss ])
}

// Syntax support:
if (result.opts.syntax && result.opts.syntax.parse) {
parserList.push(result.opts.syntax.parse)
}

// Parser support:
if (result.opts.parser) parserList.push(result.opts.parser)
// Try the default as a last resort:
parserList.push(null)

return runPostcss(content, filename, plugins, parserList)
}

function runPostcss(
content,
filename,
plugins,
parsers,
index
) {
if (!index) index = 0
return postcss(plugins).process(content, {
from: filename,
parser: parsers[index],
})
.catch(function(err) {
// If there's an error, try the next parser
index++
// If there are no parsers left, throw it
if (index === parsers.length) throw err
return runPostcss(content, filename, plugins, parsers, index)
})
}
6 changes: 2 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@
"eslint": "^1.10.3",
"eslint-config-i-am-meticulous": "^2.0.0",
"npmpub": "^3.0.1",
"postcss-scss": "^0.1.3"
},
"optionalDependencies": {
"pkg-resolve": "^0.1.7"
"postcss-scss": "^0.1.3",
"sugarss": "^0.2.0"
},
"jspm": {
"name": "postcss-import",
Expand Down
22 changes: 22 additions & 0 deletions test/custom-resolve.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import test from "ava"
import compareFixtures from "./helpers/compare-fixtures"
import postcss from "postcss"
import atImport from ".."
import path from "path"

test.serial("should accept file", t => {
Expand Down Expand Up @@ -43,3 +45,23 @@ test.serial("should accept promised array of files", t => {
},
})
})

test(
"should apply default resolver when custom doesn't return an absolute path",
function(t) {
return postcss()
.use(atImport({
resolve: path => {
return path.replace("foo", "imports/bar")
},
load: p => {
t.is(p, path.resolve("fixtures/imports", "bar.css"))
return "/* comment */"
},
}))
.process(`@import "foo.css";`, { from: "fixtures/custom-resolve-file" })
.then(result => {
t.is(result.css, "/* comment */")
})
}
)
43 changes: 43 additions & 0 deletions test/custom-syntax-parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import test from "ava"
import scss from "postcss-scss"
import sugarss from "sugarss"
import compareFixtures from "./helpers/compare-fixtures"
import compareFixturesExt from "./helpers/compare-fixtures-ext"

test("should process custom syntax", t => {
return compareFixtures(t, "scss-syntax", null, {
syntax: scss,
})
})

test("should process custom syntax by parser", t => {
return compareFixtures(t, "scss-parser", null, {
parser: scss,
})
})

test(".css importing .sss should work", t => {
return compareFixtures(t, "import-sss")
})

test(".sss importing .sss should work", t => {
return compareFixturesExt(t, "sugar", ".sss", null, {
parser: sugarss,
})
})

test(".sss importing .css should work", t => {
return compareFixturesExt(t, "sugar-import-css", ".sss", null, {
parser: sugarss,
})
})

test(".css importing .sss importing .css should work", t => {
return compareFixtures(t, "import-sss-css")
})

test(".sss importing .css importing .sss should work", t => {
return compareFixturesExt(t, "import-css-sss", ".sss", null, {
parser: sugarss,
})
})
9 changes: 9 additions & 0 deletions test/fixtures/import-css-sss.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.sugarbar{
color: blue
}

import.sugarbar{}

.sugar{
color: white
}
4 changes: 4 additions & 0 deletions test/fixtures/import-css-sss.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "import-sugarbar.css"

.sugar
color: white
1 change: 1 addition & 0 deletions test/fixtures/import-sss-css.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "foo-recursive.sss";
5 changes: 5 additions & 0 deletions test/fixtures/import-sss-css.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bar{}

foo.recursive{
color: red
}
1 change: 1 addition & 0 deletions test/fixtures/import-sss.css
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "sugarbar.sss";
3 changes: 3 additions & 0 deletions test/fixtures/import-sss.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.sugarbar {
color: blue
}
4 changes: 4 additions & 0 deletions test/fixtures/imports/foo-recursive.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@import "bar.css"

foo.recursive
color: red
3 changes: 3 additions & 0 deletions test/fixtures/imports/import-sugarbar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import "sugarbar.sss";

import.sugarbar{}
2 changes: 2 additions & 0 deletions test/fixtures/imports/sugarbar.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.sugarbar
color: blue
4 changes: 4 additions & 0 deletions test/fixtures/sugar-import-css.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bar{}
.sugar{
color: white
}
3 changes: 3 additions & 0 deletions test/fixtures/sugar-import-css.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import "bar.css"
.sugar
color: white
6 changes: 6 additions & 0 deletions test/fixtures/sugar.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.sugarbar {
color: blue
}
.sugar {
color: white
}
3 changes: 3 additions & 0 deletions test/fixtures/sugar.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@import "sugarbar.sss"
.sugar
color: white
1 change: 0 additions & 1 deletion test/fixtures/transform-content.css

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/transform-content.expected.css

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/transform-undefined.css

This file was deleted.

1 change: 0 additions & 1 deletion test/fixtures/transform-undefined.expected.css

This file was deleted.

32 changes: 32 additions & 0 deletions test/helpers/compare-fixtures-ext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
var fs = require("fs")
var postcss = require("postcss")
var assign = require("object-assign")
var atImport = require("../..")

function read(name, ext) {
if (!ext) ext = ".css"
return fs.readFileSync("fixtures/" + name + ext, "utf8")
}

module.exports = function(t, name, ext, opts, postcssOpts, warnings) {
opts = assign({ path: "fixtures/imports" }, opts)
return postcss(atImport(opts))
.process(read(name, ext), postcssOpts || {})
.then(function(result) {
var actual = result.css
var expected = read(name + ".expected")
// handy thing: checkout actual in the *.actual.css file
fs.writeFile("fixtures/" + name + ".actual.css", actual)
t.is(actual, expected)
if (!warnings) {
warnings = []
}
result.warnings().forEach(function(warning, index) {
t.is(
warning.text,
warnings[index],
"unexpected warning: \"" + warning.text + "\""
)
})
})
}
Loading

0 comments on commit 7d9099c

Please sign in to comment.