postcss-import
Advanced tools
Comparing version 12.0.1 to 13.0.0
@@ -0,1 +1,7 @@ | ||
# 13.0.0 / 2020-10-20 | ||
- **BREAKING:** Require Node 10+ ([#429](https://github.com/postcss/postcss-import/pull/429)) | ||
- **BREAKING:** Upgrade to postcss v8 and require it as a `peerDependency` ([#427](https://github.com/postcss/postcss-import/issues/427), [#432](https://github.com/postcss/postcss-import/pull/432)) | ||
- Update dependencies | ||
# 12.0.1 / 2018-10-22 | ||
@@ -2,0 +8,0 @@ |
416
index.js
@@ -5,5 +5,2 @@ "use strict" | ||
// external tooling | ||
const postcss = require("postcss") | ||
// internal tooling | ||
@@ -39,232 +36,251 @@ const joinMedia = require("./lib/join-media") | ||
return function(styles, result) { | ||
const state = { | ||
importedFiles: {}, | ||
hashFiles: {}, | ||
} | ||
return { | ||
postcssPlugin: "postcss-import", | ||
Once(styles, { result, atRule }) { | ||
const state = { | ||
importedFiles: {}, | ||
hashFiles: {}, | ||
} | ||
if (styles.source && styles.source.input && styles.source.input.file) { | ||
state.importedFiles[styles.source.input.file] = {} | ||
} | ||
if (styles.source && styles.source.input && styles.source.input.file) { | ||
state.importedFiles[styles.source.input.file] = {} | ||
} | ||
if (options.plugins && !Array.isArray(options.plugins)) { | ||
throw new Error("plugins option must be an array") | ||
} | ||
if (options.plugins && !Array.isArray(options.plugins)) { | ||
throw new Error("plugins option must be an array") | ||
} | ||
return parseStyles(result, styles, options, state, []).then(bundle => { | ||
applyRaws(bundle) | ||
applyMedia(bundle) | ||
applyStyles(bundle, styles) | ||
}) | ||
} | ||
} | ||
return parseStyles(result, styles, options, state, []).then(bundle => { | ||
applyRaws(bundle) | ||
applyMedia(bundle) | ||
applyStyles(bundle, styles) | ||
}) | ||
function applyRaws(bundle) { | ||
bundle.forEach((stmt, index) => { | ||
if (index === 0) return | ||
function applyRaws(bundle) { | ||
bundle.forEach((stmt, index) => { | ||
if (index === 0) return | ||
if (stmt.parent) { | ||
const 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" | ||
} | ||
}) | ||
} | ||
if (stmt.parent) { | ||
const 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" | ||
} | ||
}) | ||
} | ||
function applyMedia(bundle) { | ||
bundle.forEach(stmt => { | ||
if (!stmt.media.length) return | ||
if (stmt.type === "import") { | ||
stmt.node.params = `${stmt.fullUri} ${stmt.media.join(", ")}` | ||
} else if (stmt.type === "media") stmt.node.params = stmt.media.join(", ") | ||
else { | ||
const nodes = stmt.nodes | ||
const parent = nodes[0].parent | ||
const mediaNode = postcss.atRule({ | ||
name: "media", | ||
params: stmt.media.join(", "), | ||
source: parent.source, | ||
}) | ||
function applyMedia(bundle) { | ||
bundle.forEach(stmt => { | ||
if (!stmt.media.length) return | ||
if (stmt.type === "import") { | ||
stmt.node.params = `${stmt.fullUri} ${stmt.media.join(", ")}` | ||
} else if (stmt.type === "media") | ||
stmt.node.params = stmt.media.join(", ") | ||
else { | ||
const nodes = stmt.nodes | ||
const parent = nodes[0].parent | ||
const mediaNode = atRule({ | ||
name: "media", | ||
params: stmt.media.join(", "), | ||
source: parent.source, | ||
}) | ||
parent.insertBefore(nodes[0], mediaNode) | ||
parent.insertBefore(nodes[0], mediaNode) | ||
// remove nodes | ||
nodes.forEach(node => { | ||
node.parent = undefined | ||
}) | ||
// remove nodes | ||
nodes.forEach(node => { | ||
node.parent = undefined | ||
}) | ||
// better output | ||
nodes[0].raws.before = nodes[0].raws.before || "\n" | ||
// better output | ||
nodes[0].raws.before = nodes[0].raws.before || "\n" | ||
// wrap new rules with media query | ||
mediaNode.append(nodes) | ||
// wrap new rules with media query | ||
mediaNode.append(nodes) | ||
stmt.type = "media" | ||
stmt.node = mediaNode | ||
delete stmt.nodes | ||
} | ||
}) | ||
} | ||
stmt.type = "media" | ||
stmt.node = mediaNode | ||
delete stmt.nodes | ||
} | ||
}) | ||
} | ||
function applyStyles(bundle, styles) { | ||
styles.nodes = [] | ||
function applyStyles(bundle, styles) { | ||
styles.nodes = [] | ||
// Strip additional statements. | ||
bundle.forEach(stmt => { | ||
if (stmt.type === "import") { | ||
stmt.node.parent = undefined | ||
styles.append(stmt.node) | ||
} else if (stmt.type === "media") { | ||
stmt.node.parent = undefined | ||
styles.append(stmt.node) | ||
} else if (stmt.type === "nodes") { | ||
stmt.nodes.forEach(node => { | ||
node.parent = undefined | ||
styles.append(node) | ||
}) | ||
} | ||
}) | ||
} | ||
// Strip additional statements. | ||
bundle.forEach(stmt => { | ||
if (stmt.type === "import") { | ||
stmt.node.parent = undefined | ||
styles.append(stmt.node) | ||
} else if (stmt.type === "media") { | ||
stmt.node.parent = undefined | ||
styles.append(stmt.node) | ||
} else if (stmt.type === "nodes") { | ||
stmt.nodes.forEach(node => { | ||
node.parent = undefined | ||
styles.append(node) | ||
}) | ||
} | ||
}) | ||
} | ||
function parseStyles(result, styles, options, state, media) { | ||
const statements = parseStatements(result, styles) | ||
function parseStyles(result, styles, options, state, media) { | ||
const statements = parseStatements(result, styles) | ||
return Promise.resolve(statements) | ||
.then(stmts => { | ||
// process each statement in series | ||
return stmts.reduce((promise, stmt) => { | ||
return promise.then(() => { | ||
stmt.media = joinMedia(media, stmt.media || []) | ||
return Promise.resolve(statements) | ||
.then(stmts => { | ||
// process each statement in series | ||
return stmts.reduce((promise, stmt) => { | ||
return promise.then(() => { | ||
stmt.media = joinMedia(media, stmt.media || []) | ||
// skip protocol base uri (protocol://url) or protocol-relative | ||
if (stmt.type !== "import" || /^(?:[a-z]+:)?\/\//i.test(stmt.uri)) { | ||
return | ||
} | ||
// skip protocol base uri (protocol://url) or protocol-relative | ||
if ( | ||
stmt.type !== "import" || | ||
/^(?:[a-z]+:)?\/\//i.test(stmt.uri) | ||
) { | ||
return | ||
} | ||
if (options.filter && !options.filter(stmt.uri)) { | ||
// rejected by filter | ||
return | ||
} | ||
if (options.filter && !options.filter(stmt.uri)) { | ||
// rejected by filter | ||
return | ||
} | ||
return resolveImportId(result, stmt, options, state) | ||
}) | ||
}, Promise.resolve()) | ||
}) | ||
.then(() => { | ||
const imports = [] | ||
const bundle = [] | ||
return resolveImportId(result, stmt, options, state) | ||
}) | ||
}, Promise.resolve()) | ||
}) | ||
.then(() => { | ||
const imports = [] | ||
const bundle = [] | ||
// squash statements and their children | ||
statements.forEach(stmt => { | ||
if (stmt.type === "import") { | ||
if (stmt.children) { | ||
stmt.children.forEach((child, index) => { | ||
if (child.type === "import") imports.push(child) | ||
else bundle.push(child) | ||
// For better output | ||
if (index === 0) child.parent = stmt | ||
// squash statements and their children | ||
statements.forEach(stmt => { | ||
if (stmt.type === "import") { | ||
if (stmt.children) { | ||
stmt.children.forEach((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) | ||
} | ||
}) | ||
} else imports.push(stmt) | ||
} else if (stmt.type === "media" || stmt.type === "nodes") { | ||
bundle.push(stmt) | ||
return imports.concat(bundle) | ||
}) | ||
} | ||
function resolveImportId(result, stmt, options, state) { | ||
const atRule = stmt.node | ||
let sourceFile | ||
if (atRule.source && atRule.source.input && atRule.source.input.file) { | ||
sourceFile = atRule.source.input.file | ||
} | ||
}) | ||
const base = sourceFile | ||
? path.dirname(atRule.source.input.file) | ||
: options.root | ||
return imports.concat(bundle) | ||
}) | ||
} | ||
return Promise.resolve(options.resolve(stmt.uri, base, options)) | ||
.then(paths => { | ||
if (!Array.isArray(paths)) paths = [paths] | ||
// Ensure that each path is absolute: | ||
return Promise.all( | ||
paths.map(file => { | ||
return !path.isAbsolute(file) | ||
? resolveId(file, base, options) | ||
: file | ||
}) | ||
) | ||
}) | ||
.then(resolved => { | ||
// Add dependency messages: | ||
resolved.forEach(file => { | ||
result.messages.push({ | ||
type: "dependency", | ||
plugin: "postcss-import", | ||
file: file, | ||
parent: sourceFile, | ||
}) | ||
}) | ||
function resolveImportId(result, stmt, options, state) { | ||
const atRule = stmt.node | ||
let sourceFile | ||
if (atRule.source && atRule.source.input && atRule.source.input.file) { | ||
sourceFile = atRule.source.input.file | ||
} | ||
const base = sourceFile | ||
? path.dirname(atRule.source.input.file) | ||
: options.root | ||
return Promise.all( | ||
resolved.map(file => { | ||
return loadImportContent(result, stmt, file, options, state) | ||
}) | ||
) | ||
}) | ||
.then(result => { | ||
// Merge loaded statements | ||
stmt.children = result.reduce((result, statements) => { | ||
return statements ? result.concat(statements) : result | ||
}, []) | ||
}) | ||
} | ||
return Promise.resolve(options.resolve(stmt.uri, base, options)) | ||
.then(paths => { | ||
if (!Array.isArray(paths)) paths = [paths] | ||
// Ensure that each path is absolute: | ||
return Promise.all( | ||
paths.map(file => { | ||
return !path.isAbsolute(file) ? resolveId(file, base, options) : file | ||
}) | ||
) | ||
}) | ||
.then(resolved => { | ||
// Add dependency messages: | ||
resolved.forEach(file => { | ||
result.messages.push({ | ||
type: "dependency", | ||
plugin: "postcss-import", | ||
file: file, | ||
parent: sourceFile, | ||
}) | ||
}) | ||
function loadImportContent(result, stmt, filename, options, state) { | ||
const atRule = stmt.node | ||
const media = stmt.media | ||
if (options.skipDuplicates) { | ||
// skip files already imported at the same scope | ||
if ( | ||
state.importedFiles[filename] && | ||
state.importedFiles[filename][media] | ||
) { | ||
return | ||
} | ||
return Promise.all( | ||
resolved.map(file => { | ||
return loadImportContent(result, stmt, file, options, state) | ||
}) | ||
) | ||
}) | ||
.then(result => { | ||
// Merge loaded statements | ||
stmt.children = result.reduce((result, statements) => { | ||
return statements ? result.concat(statements) : result | ||
}, []) | ||
}) | ||
} | ||
// save imported files to skip them next time | ||
if (!state.importedFiles[filename]) state.importedFiles[filename] = {} | ||
state.importedFiles[filename][media] = true | ||
} | ||
function loadImportContent(result, stmt, filename, options, state) { | ||
const atRule = stmt.node | ||
const media = stmt.media | ||
if (options.skipDuplicates) { | ||
// skip files already imported at the same scope | ||
if (state.importedFiles[filename] && state.importedFiles[filename][media]) { | ||
return | ||
} | ||
return Promise.resolve(options.load(filename, options)).then( | ||
content => { | ||
if (content.trim() === "") { | ||
result.warn(`${filename} is empty`, { node: atRule }) | ||
return | ||
} | ||
// save imported files to skip them next time | ||
if (!state.importedFiles[filename]) state.importedFiles[filename] = {} | ||
state.importedFiles[filename][media] = true | ||
} | ||
// skip previous imported files not containing @import rules | ||
if (state.hashFiles[content] && state.hashFiles[content][media]) | ||
return | ||
return Promise.resolve(options.load(filename, options)).then(content => { | ||
if (content.trim() === "") { | ||
result.warn(`${filename} is empty`, { node: atRule }) | ||
return | ||
} | ||
return processContent(result, content, filename, options).then( | ||
importedResult => { | ||
const styles = importedResult.root | ||
result.messages = result.messages.concat( | ||
importedResult.messages | ||
) | ||
// skip previous imported files not containing @import rules | ||
if (state.hashFiles[content] && state.hashFiles[content][media]) return | ||
if (options.skipDuplicates) { | ||
const hasImport = styles.some(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 processContent(result, content, filename, options).then( | ||
importedResult => { | ||
const styles = importedResult.root | ||
result.messages = result.messages.concat(importedResult.messages) | ||
if (options.skipDuplicates) { | ||
const hasImport = styles.some(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 | ||
// recursion: import @import from imported file | ||
return parseStyles(result, styles, options, state, media) | ||
} | ||
) | ||
} | ||
} | ||
// recursion: import @import from imported file | ||
return parseStyles(result, styles, options, state, media) | ||
) | ||
} | ||
) | ||
}) | ||
}, | ||
} | ||
} | ||
module.exports = postcss.plugin("postcss-import", AtImport) | ||
AtImport.postcss = true | ||
module.exports = AtImport |
"use strict" | ||
module.exports = function(parentMedia, childMedia) { | ||
module.exports = function (parentMedia, childMedia) { | ||
if (!parentMedia.length && childMedia.length) return childMedia | ||
@@ -5,0 +5,0 @@ if (parentMedia.length && !childMedia.length) return parentMedia |
@@ -23,3 +23,3 @@ "use strict" | ||
module.exports = function(result, styles) { | ||
module.exports = function (result, styles) { | ||
const statements = [] | ||
@@ -26,0 +26,0 @@ let nodes = [] |
@@ -14,3 +14,3 @@ "use strict" | ||
module.exports = function(id, base, options) { | ||
module.exports = function (id, base, options) { | ||
const paths = options.path | ||
@@ -17,0 +17,0 @@ |
{ | ||
"name": "postcss-import", | ||
"version": "12.0.1", | ||
"version": "13.0.0", | ||
"description": "PostCSS plugin to import CSS files", | ||
@@ -21,7 +21,6 @@ "keywords": [ | ||
"engines": { | ||
"node": ">=6.0.0" | ||
"node": ">=10.0.0" | ||
}, | ||
"dependencies": { | ||
"postcss": "^7.0.1", | ||
"postcss-value-parser": "^3.2.3", | ||
"postcss-value-parser": "^4.0.0", | ||
"read-cache": "^1.0.0", | ||
@@ -31,11 +30,15 @@ "resolve": "^1.1.7" | ||
"devDependencies": { | ||
"ava": "^0.25.0", | ||
"ava": "^1.0.1", | ||
"eslint": "^5.0.0", | ||
"eslint-config-i-am-meticulous": "^11.0.0", | ||
"eslint-plugin-import": "^2.2.0", | ||
"eslint-plugin-import": "^2.17.1", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"postcss-scss": "^2.0.0", | ||
"prettier": "~1.14.0", | ||
"sugarss": "^2.0.0" | ||
"postcss": "^8.0.0", | ||
"postcss-scss": "^3.0.0", | ||
"prettier": "~2.1.0", | ||
"sugarss": "^3.0.0" | ||
}, | ||
"peerDependencies": { | ||
"postcss": "^8.0.0" | ||
}, | ||
"scripts": { | ||
@@ -57,3 +60,3 @@ "ci": "eslint . && ava", | ||
"semi": false, | ||
"trailingComma": "es5" | ||
"arrowParens": "avoid" | ||
} | ||
@@ -60,0 +63,0 @@ ] |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
36019
463
9
+ Addednanoid@3.3.7(transitive)
+ Addedpicocolors@1.1.1(transitive)
+ Addedpostcss@8.4.47(transitive)
+ Addedpostcss-value-parser@4.2.0(transitive)
+ Addedsource-map-js@1.2.1(transitive)
- Removedpostcss@^7.0.1
- Removedpicocolors@0.2.1(transitive)
- Removedpostcss@7.0.39(transitive)
- Removedpostcss-value-parser@3.3.1(transitive)
- Removedsource-map@0.6.1(transitive)
Updatedpostcss-value-parser@^4.0.0