Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

postcss-import

Package Overview
Dependencies
Maintainers
1
Versions
54
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-import - npm Package Compare versions

Comparing version 7.1.3 to 8.0.0

56

CHANGELOG.md

@@ -0,1 +1,57 @@

# 8.0.0 - 2015-01-27
- Removed: async mode/option (now async by default)
([#107](https://github.com/postcss/postcss-import/pull/107))
- Removed: "bower_components" not supported by default anymore,
use "path" option to add it back
- Removed: `encoding` option. Encoding can be specified in custom `load` option
```js
postcssImport({
load: function(filename) {
return fs.readFileSync(filename, "utf-8")
}
})
```
([#144](https://github.com/postcss/postcss-import/pull/144))
- Removed: glob support
([#146](https://github.com/postcss/postcss-import/pull/146))
Globs can be implemented with custom `resolve` option
```js
postcssImport({
resolve: function(id, base) {
return glob.sync(path.join(base, id))
}
})
```
([#116](https://github.com/postcss/postcss-import/pull/116))
- Changed: custom resolve has more responsibility for paths resolving.
See [resolve option](https://github.com/postcss/postcss-import#resolve)
for more information about this change
([#116](https://github.com/postcss/postcss-import/pull/116))
- Changed: support promise in `transform` option and `undefined` result will be
skipped
([#147](https://github.com/postcss/postcss-import/pull/147))
- Changed: `options.plugins` are applied to unprocessed ast before imports
detecting
([157](https://github.com/postcss/postcss-import/pull/157))
- Added: custom resolve function can return array of paths
([#120](https://github.com/postcss/postcss-import/pull/120))
- Added: custom syntax in imported files support
([#130](https://github.com/postcss/postcss-import/pull/130))
- Added: support custom `load` option
([#144](https://github.com/postcss/postcss-import/pull/144))
- Added: detect css extension in package.json `main` field
([153](https://github.com/postcss/postcss-import/pull/153))
**Note:**
_If you miss options/default behavior (glob etc), a new plugin will handle all
those things.
Please follow issue [#145](https://github.com/postcss/postcss-import/issues/145)
_
# 7.1.3 - 2015-11-05

@@ -2,0 +58,0 @@

722

index.js

@@ -1,43 +0,21 @@

/**
* Module dependencies.
*/
var fs = require("fs")
var path = require("path")
var assign = require("object-assign")
var resolve = require("resolve")
var postcss = require("postcss")
var helpers = require("postcss-message-helpers")
var glob = require("glob")
var joinMedia = require("./lib/join-media")
var resolveId = require("./lib/resolve-id")
var loadContent = require("./lib/load-content")
var parseStatements = require("./lib/parse-statements")
var resolvedPromise = new Promise(function(resolvePromise) {
resolvePromise()
})
/**
* Constants
*/
var moduleDirectories = [
"web_modules",
"node_modules",
"bower_components",
]
var warnNodesMessage =
"It looks like you didn't end correctly your @import statement. " +
"Some children nodes are attached to it."
/**
* Inline `@import`ed files
*
* @param {Object} options
*/
function AtImport(options) {
options = assign({
root: process.cwd(),
async: false,
path: [],
skipDuplicates: true,
}, options || {})
resolve: resolveId,
load: loadContent,
plugins: [],
}, options)
options.root = path.resolve(options.root)
// convert string to an array of a single element

@@ -48,523 +26,312 @@ if (typeof options.path === "string") {

return function(styles, result) {
var opts = assign({}, options || {})
if (!Array.isArray(options.path)) {
options.path = []
}
// auto add from option if possible
if (
!opts.from &&
styles &&
styles.nodes &&
styles.nodes[0] &&
styles.nodes[0].source &&
styles.nodes[0].source.input &&
styles.nodes[0].source.input.file
) {
opts.from = styles.nodes[0].source.input.file
}
options.path = options.path.map(function(p) {
return path.resolve(options.root, p)
})
// if from available, prepend from directory in the path array
addInputToPath(opts)
// if we got nothing for the path, just use cwd
if (opts.path.length === 0) {
opts.path.push(process.cwd())
}
return function(styles, result) {
var state = {
importedFiles: {},
ignoredAtRules: [],
hashFiles: {},
}
if (opts.from) {
state.importedFiles[opts.from] = {
"": true,
}
if (styles.source && styles.source.input && styles.source.input.file) {
state.importedFiles[styles.source.input.file] = {}
}
var parsedStylesResult = parseStyles(
if (options.plugins && !Array.isArray(options.plugins)) {
throw new Error("plugins option must be an array")
}
return parseStyles(
result,
styles,
opts,
options,
state,
null,
createProcessor(result, options.plugins)
)
[]
).then(function(bundle) {
function onParseEnd() {
addIgnoredAtRulesOnTop(styles, state.ignoredAtRules)
applyRaws(bundle)
applyMedia(bundle)
applyStyles(bundle, styles)
if (
typeof opts.addDependencyTo === "object" &&
typeof opts.addDependencyTo.addDependency === "function"
typeof options.addDependencyTo === "object" &&
typeof options.addDependencyTo.addDependency === "function"
) {
Object.keys(state.importedFiles)
.forEach(opts.addDependencyTo.addDependency)
.forEach(options.addDependencyTo.addDependency)
}
if (typeof opts.onImport === "function") {
opts.onImport(Object.keys(state.importedFiles))
if (typeof options.onImport === "function") {
options.onImport(Object.keys(state.importedFiles))
}
}
if (options.async) {
return parsedStylesResult.then(onParseEnd)
}
// else (!options.async)
onParseEnd()
})
}
}
function createProcessor(result, plugins) {
if (plugins) {
if (!Array.isArray(plugins)) {
throw new Error("plugins option must be an array")
function applyRaws(bundle) {
bundle.forEach(function(stmt, index) {
if (index === 0) {
return
}
return postcss(plugins)
}
return postcss()
if (stmt.parent) {
var before = stmt.parent.node.raws.before
if (stmt.type === "nodes") {
stmt.nodes[0].raws.before = before
}
else {
stmt.node.raws.before = before
}
}
else if (stmt.type === "nodes") {
stmt.nodes[0].raws.before = stmt.nodes[0].raws.before || "\n"
}
})
}
/**
* lookup for @import rules
*
* @param {Object} styles
* @param {Object} options
*/
function parseStyles(
result,
styles,
options,
state,
media,
processor
) {
var imports = []
styles.walkAtRules("import", function checkAtRule(atRule) {
if (atRule.nodes) {
result.warn(warnNodesMessage, { node: atRule })
function applyMedia(bundle) {
bundle.forEach(function(stmt) {
if (!stmt.media.length) {
return
}
if (options.glob && glob.hasMagic(atRule.params)) {
imports = parseGlob(atRule, options, imports)
if (stmt.type === "import") {
stmt.node.params = stmt.fullUri + " " + stmt.media.join(", ")
}
else if (stmt.type ==="media") {
stmt.node.params = stmt.media.join(", ")
}
else {
imports.push(atRule)
}
})
var nodes = stmt.nodes
var parent = nodes[0].parent
var mediaNode = postcss.atRule({
name: "media",
params: stmt.media.join(", "),
source: parent.source,
})
var importResults = imports.map(function(atRule) {
return helpers.try(function transformAtImport() {
return readAtImport(
result,
atRule,
options,
state,
media,
processor
)
}, atRule.source)
})
parent.insertBefore(nodes[0], mediaNode)
if (options.async) {
return Promise.all(importResults)
}
// else (!options.async)
// nothing
}
// remove nodes
nodes.forEach(function(node) {
node.parent = undefined
})
/**
* parse glob patterns (for relative paths only)
*
* @param {Object} atRule
* @param {Object} options
* @param {Array} imports
*/
function parseGlob(atRule, options, imports) {
var globPattern = atRule.params
.replace(/['"]/g, "")
.replace(/(?:url\(|\))/g, "")
var paths = options.path.concat(moduleDirectories)
var files = []
var dir = options.source && options.source.input && options.source.input.file
? path.dirname(path.resolve(options.root, options.source.input.file))
: options.root
// better output
nodes[0].raws.before = nodes[0].raws.before || "\n"
paths.forEach(function(p) {
p = path.resolve(dir, p)
var globbed = glob.sync(path.join(p, globPattern))
globbed.forEach(function(file) {
file = path.relative(p, file)
files.push(file)
})
})
// wrap new rules with media query
mediaNode.append(nodes)
files.forEach(function(file) {
var deglobbedAtRule = atRule.clone({
params: "\"" + file + "\"",
})
if (
deglobbedAtRule.source &&
deglobbedAtRule.source.input &&
deglobbedAtRule.source.input.css
) {
deglobbedAtRule.source.input.css = atRule.source.input.css
.replace(globPattern, file)
stmt.type = "media"
stmt.node = mediaNode
delete stmt.nodes
}
atRule.parent.insertBefore(atRule, deglobbedAtRule)
imports.push(deglobbedAtRule)
})
atRule.remove()
return imports
}
/**
* put back at the top ignored url (absolute url)
*
* @param {Object} styles
* @param {Array} state
*/
function addIgnoredAtRulesOnTop(styles, ignoredAtRules) {
var i = ignoredAtRules.length
if (i) {
var first = styles.first
function applyStyles(bundle, styles) {
styles.nodes = []
while (i--) {
var ignoredAtRule = ignoredAtRules[i][0]
ignoredAtRule.params = ignoredAtRules[i][1].fullUri +
(ignoredAtRules[i][1].media ? " " + ignoredAtRules[i][1].media : "")
// keep ast ref
ignoredAtRule.parent = styles
// don't use prepend() to avoid weird behavior of normalize()
styles.nodes.unshift(ignoredAtRule)
bundle.forEach(function(stmt) {
if (stmt.type === "import") {
stmt.node.parent = undefined
styles.append(stmt.node)
}
// separate remote import a little with others rules if no newlines already
if (first &&
first.raws.before.indexOf("\n") === -1) {
first.raws.before = "\n\n" + first.raws.before
else if (stmt.type === "media") {
stmt.node.parent = undefined
styles.append(stmt.node)
}
}
else if (stmt.type === "nodes") {
stmt.nodes.forEach(function(node) {
node.parent = undefined
styles.append(node)
})
}
})
}
/**
* parse @import rules & inline appropriate rules
*
* @param {Object} atRule postcss atRule
* @param {Object} options
*/
function readAtImport(
function parseStyles(
result,
atRule,
styles,
options,
state,
media,
processor
media
) {
// parse-import module parse entire line
// @todo extract what can be interesting from this one
var parsedAtImport = parseImport(atRule.params, atRule.source)
var statements = parseStatements(result, styles)
// adjust media according to current scope
media = parsedAtImport.media
? (media ? media + " and " : "") + parsedAtImport.media
: (media ? media : null)
return Promise.all(statements.map(function(stmt) {
stmt.media = joinMedia(media, stmt.media)
// just update protocol base uri (protocol://url) or protocol-relative
// (//url) if media needed
if (parsedAtImport.uri.match(/^(?:[a-z]+:)?\/\//i)) {
parsedAtImport.media = media
// skip protocol base uri (protocol://url) or protocol-relative
if (stmt.type !== "import" || /^(?:[a-z]+:)?\/\//i.test(stmt.uri)) {
return
}
return resolveImportId(
result,
stmt,
options,
state
)
})).then(function() {
var imports = []
var bundle = []
// save
state.ignoredAtRules.push([ atRule, parsedAtImport ])
// squash statements and their children
statements.forEach(function(stmt) {
if (stmt.type === "import") {
if (stmt.children) {
stmt.children.forEach(function(child, index) {
if (child.type === "import") {
imports.push(child)
}
else {
bundle.push(child)
}
// For better output
if (index === 0) {
child.parent = stmt
}
})
}
else {
imports.push(stmt)
}
}
else if (stmt.type === "media" || stmt.type === "nodes") {
bundle.push(stmt)
}
})
// detach
detach(atRule)
return imports.concat(bundle)
})
}
return resolvedPromise
}
function resolveImportId(
result,
stmt,
options,
state
) {
var atRule = stmt.node
var base = atRule.source && atRule.source.input && atRule.source.input.file
? path.dirname(atRule.source.input.file)
: options.root
addInputToPath(options)
var resolvedFilename = resolveFilename(
parsedAtImport.uri,
options.root,
options.path,
atRule.source,
options.resolve
)
return Promise.resolve(options.resolve(stmt.uri, base, options))
.then(function(resolved) {
if (!Array.isArray(resolved)) {
resolved = [ resolved ]
}
return Promise.all(resolved.map(function(file) {
return loadImportContent(
result,
stmt,
file,
options,
state
)
}))
})
.then(function(result) {
// Merge loaded statements
stmt.children = result.reduce(function(result, statements) {
if (statements) {
result = result.concat(statements)
}
return result
}, [])
})
.catch(function(err) {
result.warn(err.message, { node: atRule })
})
}
function loadImportContent(
result,
stmt,
filename,
options,
state
) {
var atRule = stmt.node
var media = stmt.media
if (options.skipDuplicates) {
// skip files already imported at the same scope
if (
state.importedFiles[resolvedFilename] &&
state.importedFiles[resolvedFilename][media]
state.importedFiles[filename] &&
state.importedFiles[filename][media]
) {
detach(atRule)
return resolvedPromise
return
}
// save imported files to skip them next time
if (!state.importedFiles[resolvedFilename]) {
state.importedFiles[resolvedFilename] = {}
if (!state.importedFiles[filename]) {
state.importedFiles[filename] = {}
}
state.importedFiles[resolvedFilename][media] = true
state.importedFiles[filename][media] = true
}
return readImportedContent(
result,
atRule,
parsedAtImport,
assign({}, options),
resolvedFilename,
state,
media,
processor
)
}
/**
* insert imported content at the right place
*
* @param {Object} atRule
* @param {Object} parsedAtImport
* @param {Object} options
* @param {String} resolvedFilename
*/
function readImportedContent(
result,
atRule,
parsedAtImport,
options,
resolvedFilename,
state,
media,
processor
) {
// add directory containing the @imported file in the paths
// to allow local import from this file
var dirname = path.dirname(resolvedFilename)
if (options.path.indexOf(dirname) === -1) {
options.path = options.path.slice()
options.path.unshift(dirname)
}
options.from = resolvedFilename
var fileContent = readFile(
resolvedFilename,
options.encoding,
options.transform || function(value) {
return value
return Promise.resolve(options.load(filename, options))
.then(function(content) {
if (typeof options.transform !== "function") {
return content
}
)
if (fileContent.trim() === "") {
result.warn(resolvedFilename + " is empty", { node: atRule })
detach(atRule)
return resolvedPromise
}
// skip previous imported files not containing @import rules
if (
state.hashFiles[fileContent] &&
state.hashFiles[fileContent][media]
) {
detach(atRule)
return resolvedPromise
}
var newStyles = postcss.parse(fileContent, options)
if (options.skipDuplicates) {
var hasImport = newStyles.some(function(child) {
return child.type === "atrule" && child.name === "import"
return Promise.resolve(options.transform(content, filename, options))
.then(function(transformed) {
return typeof transformed === "string" ? transformed : content
})
if (!hasImport) {
// save hash files to skip them next time
if (!state.hashFiles[fileContent]) {
state.hashFiles[fileContent] = {}
}
state.hashFiles[fileContent][media] = true
})
.then(function(content) {
if (content.trim() === "") {
result.warn(filename + " is empty", { node: atRule })
return
}
}
// recursion: import @import from imported file
var parsedResult = parseStyles(
result,
newStyles,
options,
state,
parsedAtImport.media,
processor
)
if (options.async) {
return parsedResult.then(function() {
return processor.process(newStyles)
.then(function(newResult) {
result.messages = result.messages.concat(newResult.messages)
})
})
.then(function() {
insertRules(atRule, parsedAtImport, newStyles)
})
}
// else (!options.async)
var newResult = processor.process(newStyles)
result.messages = result.messages.concat(newResult.messages)
insertRules(atRule, parsedAtImport, newStyles)
}
/**
* insert new imported rules at the right place
*
* @param {Object} atRule
* @param {Object} parsedAtImport
* @param {Object} newStyles
*/
function insertRules(atRule, parsedAtImport, newStyles) {
var newNodes = newStyles.nodes
// wrap rules if the @import have a media query
if (parsedAtImport.media && parsedAtImport.media.length) {
// better output
if (newStyles.nodes && newStyles.nodes.length) {
newStyles.nodes[0].raws.before = newStyles.nodes[0].raws.before || "\n"
// skip previous imported files not containing @import rules
if (
state.hashFiles[content] &&
state.hashFiles[content][media]
) {
return
}
// wrap new rules with media (media query)
var wrapper = postcss.atRule({
name: "media",
params: parsedAtImport.media,
return postcss(options.plugins).process(content, {
from: filename,
syntax: result.opts.syntax,
parser: result.opts.parser,
})
.then(function(importedResult) {
var styles = importedResult.root
result.messages = result.messages.concat(importedResult.messages)
// keep AST clean
newNodes.forEach(function(node) {
node.parent = wrapper
})
wrapper.source = atRule.source
// copy code style
wrapper.raws.before = atRule.raws.before
wrapper.raws.after = atRule.raws.after
// move nodes
wrapper.nodes = newNodes
newNodes = [ wrapper ]
}
else if (newNodes && newNodes.length) {
newNodes[0].raws.before = atRule.raws.before
}
// keep AST clean
newNodes.forEach(function(node) {
node.parent = atRule.parent
})
// replace atRule by imported nodes
var nodes = atRule.parent.nodes
nodes.splice.apply(nodes, [ nodes.indexOf(atRule), 0 ].concat(newNodes))
detach(atRule)
}
/**
* parse @import parameter
*/
function parseImport(str, source) {
var regex = /((?:url\s?\()?(?:'|")?([^)'"]+)(?:'|")?\)?)(?:(?:\s)(.*))?/gi
var matches = regex.exec(str)
if (matches === null) {
throw new Error("Unable to find uri in '" + str + "'", source)
}
return {
fullUri: matches[1],
uri: matches[2],
media: matches[3] ? matches[3] : null,
}
}
/**
* Check if a file exists
*
* @param {String} name
*/
function resolveFilename(name, root, paths, source, resolver) {
var dir = source && source.input && source.input.file
? path.dirname(path.resolve(root, source.input.file))
: root
try {
var resolveOpts = {
basedir: dir,
moduleDirectory: moduleDirectories.concat(paths),
paths: paths,
extensions: [ ".css" ],
packageFilter: function processPackage(pkg) {
pkg.main = pkg.style || "index.css"
return pkg
},
}
var file
resolver = resolver || resolve.sync
try {
file = resolver(name, resolveOpts)
}
catch (e) {
// fix to try relative files on windows with "./"
// if it's look like it doesn't start with a relative path already
// if (name.match(/^\.\.?/)) {throw e}
try {
file = resolver("./" + name, resolveOpts)
}
catch (err) {
// LAST HOPE
if (!paths.some(function(dir2) {
file = path.join(dir2, name)
return fs.existsSync(file)
})) {
throw err
if (options.skipDuplicates) {
var hasImport = styles.some(function(child) {
return child.type === "atrule" && child.name === "import"
})
if (!hasImport) {
// save hash files to skip them next time
if (!state.hashFiles[content]) {
state.hashFiles[content] = {}
}
state.hashFiles[content][media] = true
}
}
}
return path.normalize(file)
}
catch (e) {
throw new Error(
"Failed to find '" + name + "' from " + root +
"\n in [ " +
"\n " + paths.join(",\n ") +
"\n ]",
source
)
}
// recursion: import @import from imported file
return parseStyles(
result,
styles,
options,
state,
media
)
})
})
}
/**
* Read the contents of a file
*
* @param {String} file
*/
function readFile(file, encoding, transform) {
return transform(fs.readFileSync(file, encoding || "utf8"), file)
}
/**
* add `from` dirname to `path` if not already present
*
* @param {Object} options
*/
function addInputToPath(options) {
if (options.from) {
var fromDir = path.dirname(options.from)
if (options.path.indexOf(fromDir) === -1) {
options.path.unshift(fromDir)
}
}
}
function detach(node) {
node.parent.nodes.splice(node.parent.nodes.indexOf(node), 1)
}
module.exports = postcss.plugin(

@@ -574,2 +341,1 @@ "postcss-import",

)
module.exports.warnNodesMessage = warnNodesMessage
{
"name": "postcss-import",
"version": "7.1.3",
"version": "8.0.0",
"description": "PostCSS plugin to import CSS files",

@@ -20,55 +20,24 @@ "keywords": [

"dependencies": {
"glob": "^5.0.14",
"object-assign": "^4.0.1",
"postcss": "^5.0.2",
"postcss-message-helpers": "^2.0.0",
"resolve": "^1.1.6"
"postcss": "^5.0.14",
"postcss-value-parser": "^3.2.3",
"read-cache": "^1.0.0",
"resolve": "^1.1.7"
},
"devDependencies": {
"css-whitespace": "^1.1.1",
"eslint": "^1.1.0",
"tape": "^4.0.3"
"ava": "^0.11.0",
"eslint": "^1.10.3",
"eslint-config-i-am-meticulous": "^2.0.0",
"npmpub": "^3.0.1",
"postcss-scss": "^0.1.3"
},
"scripts": {
"eslint": "eslint .",
"tape": "tape test",
"test": "npm run eslint && npm run tape"
"lint": "eslint .",
"pretest": "npm run lint",
"test": "ava",
"release": "npmpub"
},
"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 ]
}
"extends": "eslint-config-i-am-meticulous/es5"
}
}

@@ -1,11 +0,17 @@

# postcss-import [![Travis Build Status](https://travis-ci.org/postcss/postcss-import.svg)](https://travis-ci.org/postcss/postcss-import) [![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/u8l6u3lr6s5u5tpi?svg=true)](https://ci.appveyor.com/project/MoOx/postcss-import)
# postcss-import
> [PostCSS](https://github.com/postcss/postcss) plugin to transform `@import` rules by inlining content.
[![Unix Build status](https://img.shields.io/travis/postcss/postcss-import/master.svg?branch=master&label=unix%20build)](https://travis-ci.org/postcss/postcss-import)
[![Windows Build status](https://img.shields.io/appveyor/ci/MoOx/postcss-import/master.svg?label=window%20build)](https://ci.appveyor.com/project/MoOx/postcss-import/branch/master)
[![Version](https://img.shields.io/npm/v/postcss-import.svg)](https://github.com/postcss/postcss-import/blob/master/CHANGELOG.md)
> [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`, `web_modules`, `bower_components`
(by default `process.cwd()`), `web_modules`, `node_modules`
or local modules.
_When importing a module, it will looks for `index.css` or file referenced in
`package.json` in the `style` field._
`package.json` in the `style` or `main` fields._
You can also provide manually multiples paths where to look at.

@@ -15,7 +21,13 @@

- **This plugin should probably be used as the first plugin of your list. This way, other plugins will work on the AST as if there were only a single file to process, and will probably work as you can expect**.
- This plugin works great with [postcss-url](https://github.com/postcss/postcss-url) plugin,
which will allow you to adjust assets `url()` (or even inline them) after inlining imported files.
- In order to optimize output, **this plugin will only import a file once** on a given scope (root, media query...).
Tests are made from the path & the content of imported files (using a hash table).
- **This plugin should probably be used as the first plugin of your list.
This way, other plugins will work on the AST as if there were only a single file
to process, and will probably work as you can expect**.
- This plugin works great with
[postcss-url](https://github.com/postcss/postcss-url) plugin,
which will allow you to adjust assets `url()` (or even inline them) after
inlining imported files.
- In order to optimize output, **this plugin will only import a file once** on
a given scope (root, media query...).
Tests are made from the path & the content of imported files (using a hash
table).
If this behavior is not what you want, look at `skipDuplicates` option

@@ -31,3 +43,5 @@

If your stylesheets are not in the same place where you run postcss (`process.cwd()`), you will need to use `from` option to make relative imports work from input dirname.
If your stylesheets are not in the same place where you run postcss
(`process.cwd()`), you will need to use `from` option to make relative imports
work from input dirname.

@@ -44,3 +58,3 @@ ```js

// process css
var output = postcss()
postcss()
.use(atImport())

@@ -51,5 +65,7 @@ .process(css, {

})
.css
.then(function (result) {
var output = result.css
console.log(output)
console.log(output)
})
```

@@ -60,7 +76,6 @@

```css
/* can consume `node_modules`, `web_modules`, `bower_components` or local modules */
/* can consume `node_modules`, `web_modules` or local modules */
@import "cssrecipes-defaults"; /* == @import "./node_modules/cssrecipes-defaults/index.css"; */
@import "normalize.css"; /* == @import "./node_modules/normalize.css/normalize.css"; */
@import "normalize.css/normalize"; /* == @import "./bower_components/normalize.css/normalize.css"; */
@import "css/foo.css"; /* relative to stylesheets/ according to `from` option above */

@@ -78,6 +93,5 @@

```css
/* ... content of ./node_modules/my-css-on-npm/index.css */
/* ... content of ./node_modules/cssrecipes-defaults/index.css */
/* ... content of ./node_modules/normalize.css/normalize.css */
/* ... content of ./bower_components/my-css-on-bower/index.css */
/* ... content of foo.css */

@@ -101,5 +115,9 @@

Type: `String`
Default: `process.cwd()`
Default: `process.cwd()` or _dirname of
[the postcss `from`](https://github.com/postcss/postcss#node-source)_
Define the root where to resolve path (eg: place where `node_modules` and `bower_components` are). Should not be used that much.
Define the root where to resolve path (eg: place where `node_modules` are).
Should not be used that much.
_Note: nested `@import` will additionally benefit of the relative dirname of
imported files._

@@ -109,16 +127,6 @@ #### `path`

Type: `String|Array`
Default: `process.cwd()` or _dirname of [the postcss `from`](https://github.com/postcss/postcss#node-source)_
Default: `[]`
A string or an array of paths in where to look for files.
_Note: nested `@import` will additionally benefit of the relative dirname of imported files._
A string or an array of paths in where to look for files.
#### `async`
Type: `Boolean`
Default: `false`
Allow to enable PostCSS async API usage. Before enabling this, check that your
runner allow async usage.
_Note: this is not enabling async fs read yet._
#### `transform`

@@ -129,3 +137,5 @@

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

@@ -137,11 +147,4 @@ #### `plugins`

An array of plugins to be applied on each imported file.
An array of plugins to be applied on each imported files.
#### `encoding`
Type: `String`
Default: `utf8`
Use if your CSS is encoded in anything other than UTF-8.
#### `onImport`

@@ -152,17 +155,23 @@

Function called after the import process. Take one argument (array of imported files).
Function called after the import process. Take one argument (array of imported
files).
#### `glob`
#### `resolve`
Type: `Boolean`
Default: `false`
Type: `Function`
Default: `null`
Set to `true` if you want @import rules to parse glob patterns.
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.
#### `resolve`
#### `load`
Type: `Function`
Default: `null`
Default: null
You can overwrite the default path resolving way by setting this option, using the `resolve.sync(id, opts)` signature that [resolve.sync](https://github.com/substack/node-resolve#resolvesyncid-opts) has.
You can overwrite the default loading way by setting this option.
This function gets `(filename, importOptions)` arguments and returns content or
promised content.

@@ -203,3 +212,3 @@ #### `skipDuplicates`

var css = postcss()
postcss()
.use(atImport({

@@ -210,3 +219,5 @@ path: ["src/css"]

.process(cssString)
.css
.then(function (result) {
var css = result.css
})
```

@@ -213,0 +224,0 @@

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc