@@ -3,5 +3,4 @@ build | |||
yarn-error.log | |||
test/dist | |||
package-lock.json | |||
dist | |||
test/dist |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||
</component> | |||
</project> |
@@ -0,0 +1,180 @@ | |||
import { | |||
ensureDir, | |||
readFile, | |||
readdirSync, | |||
statSync, | |||
writeFile | |||
} from "fs-extra"; | |||
import {TextDecoder} from "util"; | |||
import path from "path"; | |||
import tmp from "tmp"; | |||
import postcss from "postcss"; | |||
import postcssModules from "postcss-modules"; | |||
import less from "less"; | |||
import stylus from "stylus"; | |||
import resolveFile from "resolve-file"; | |||
const defaultOptions = { | |||
plugins: [], | |||
modules: true, | |||
rootDir: process.cwd(), | |||
sassOptions: {}, | |||
lessOptions: {}, | |||
stylusOptions: {}, | |||
fileIsModule: null | |||
}; | |||
const postCSSPlugin = ({ | |||
plugins = [], | |||
modules = true, | |||
rootDir = process.cwd(), | |||
sassOptions = {}, | |||
lessOptions = {}, | |||
stylusOptions = {}, | |||
fileIsModule | |||
} = defaultOptions) => ({ | |||
name: "postcss2", | |||
setup(build) { | |||
const tmpDirPath = tmp.dirSync().name, modulesMap = []; | |||
const modulesPlugin = postcssModules({ | |||
generateScopedName: "[name]__[local]___[hash:base64:5]", | |||
...typeof modules !== "boolean" ? modules : {}, | |||
getJSON(filepath, json, outpath) { | |||
const mapIndex = modulesMap.findIndex((m) => m.path === filepath); | |||
if (mapIndex !== -1) { | |||
modulesMap[mapIndex].map = json; | |||
} else { | |||
modulesMap.push({ | |||
path: filepath, | |||
map: json | |||
}); | |||
} | |||
if (typeof modules !== "boolean" && typeof modules.getJSON === "function") | |||
return modules.getJSON(filepath, json, outpath); | |||
} | |||
}); | |||
build.onResolve({filter: /.\.(css|sass|scss|less|styl)$/}, async (args) => { | |||
if (args.namespace !== "file" && args.namespace !== "") | |||
return; | |||
let sourceFullPath = resolveFile(args.path); | |||
if (!sourceFullPath) | |||
sourceFullPath = path.resolve(args.resolveDir, args.path); | |||
const sourceExt = path.extname(sourceFullPath); | |||
const sourceBaseName = path.basename(sourceFullPath, sourceExt); | |||
const isModule = fileIsModule ? fileIsModule(sourceFullPath) : sourceBaseName.match(/\.module$/); | |||
const sourceDir = path.dirname(sourceFullPath); | |||
const watchFiles = [sourceFullPath]; | |||
let tmpFilePath; | |||
if (args.kind === "entry-point") { | |||
const sourceRelDir = path.relative(path.dirname(rootDir), path.dirname(sourceFullPath)); | |||
tmpFilePath = path.resolve(tmpDirPath, sourceRelDir, `${sourceBaseName}.css`); | |||
await ensureDir(path.dirname(tmpFilePath)); | |||
} else { | |||
const uniqueTmpDir = path.resolve(tmpDirPath, uniqueId()); | |||
tmpFilePath = path.resolve(uniqueTmpDir, `${sourceBaseName}.css`); | |||
} | |||
await ensureDir(path.dirname(tmpFilePath)); | |||
const fileContent = await readFile(sourceFullPath); | |||
let css = sourceExt === ".css" ? fileContent : ""; | |||
if (sourceExt === ".sass" || sourceExt === ".scss") { | |||
const sassResult = await renderSass({ | |||
...sassOptions, | |||
file: sourceFullPath | |||
}); | |||
css = sassResult.css.toString(); | |||
watchFiles.push(...sassResult.stats.includedFiles); | |||
} | |||
if (sourceExt === ".styl") | |||
css = await renderStylus(new TextDecoder().decode(fileContent), { | |||
...stylusOptions, | |||
filename: sourceFullPath | |||
}); | |||
if (sourceExt === ".less") | |||
css = (await less.render(new TextDecoder().decode(fileContent), { | |||
...lessOptions, | |||
filename: sourceFullPath, | |||
rootpath: path.dirname(args.path) | |||
})).css; | |||
const result = await postcss(isModule ? [modulesPlugin, ...plugins] : plugins).process(css, { | |||
from: sourceFullPath, | |||
to: tmpFilePath | |||
}); | |||
watchFiles.push(...getPostCssDependencies(result.messages)); | |||
await writeFile(tmpFilePath, result.css); | |||
return { | |||
namespace: isModule ? "postcss-module" : "file", | |||
path: tmpFilePath, | |||
watchFiles, | |||
pluginData: { | |||
originalPath: sourceFullPath | |||
} | |||
}; | |||
}); | |||
build.onLoad({filter: /.*/, namespace: "postcss-module"}, async (args) => { | |||
const mod = modulesMap.find(({path: path2}) => path2 === args?.pluginData?.originalPath), resolveDir = path.dirname(args.path); | |||
return { | |||
resolveDir, | |||
contents: `import ${JSON.stringify(args.path)}; | |||
export default ${JSON.stringify(mod && mod.map ? mod.map : {})};` | |||
}; | |||
}); | |||
} | |||
}); | |||
function renderSass(options) { | |||
return new Promise((resolve, reject) => { | |||
getSassImpl().render(options, (e, res) => { | |||
if (e) | |||
reject(e); | |||
else | |||
resolve(res); | |||
}); | |||
}); | |||
} | |||
function renderStylus(str, options) { | |||
return new Promise((resolve, reject) => { | |||
stylus.render(str, options, (e, res) => { | |||
if (e) | |||
reject(e); | |||
else | |||
resolve(res); | |||
}); | |||
}); | |||
} | |||
function getSassImpl() { | |||
let impl = "sass"; | |||
try { | |||
require.resolve("sass"); | |||
} catch { | |||
try { | |||
require.resolve("node-sass"); | |||
impl = "node-sass"; | |||
} catch { | |||
throw new Error('Please install "sass" or "node-sass" package'); | |||
} | |||
} | |||
return require(impl); | |||
} | |||
function getFilesRecursive(directory) { | |||
return readdirSync(directory).reduce((files, file) => { | |||
const name = path.join(directory, file); | |||
return statSync(name).isDirectory() ? [...files, ...getFilesRecursive(name)] : [...files, name]; | |||
}, []); | |||
} | |||
let idCounter = 0; | |||
function uniqueId() { | |||
return Date.now().toString(16) + (idCounter++).toString(16); | |||
} | |||
function getPostCssDependencies(messages) { | |||
let dependencies = []; | |||
for (const message of messages) { | |||
if (message.type == "dir-dependency") { | |||
dependencies.push(...getFilesRecursive(message.dir)); | |||
} else if (message.type == "dependency") { | |||
dependencies.push(message.file); | |||
} | |||
} | |||
return dependencies; | |||
} | |||
var src_default = postCSSPlugin; | |||
export { | |||
src_default as default, | |||
defaultOptions | |||
}; |
@@ -0,0 +1,197 @@ | |||
var __create = Object.create; | |||
var __defProp = Object.defineProperty; | |||
var __getProtoOf = Object.getPrototypeOf; | |||
var __hasOwnProp = Object.prototype.hasOwnProperty; | |||
var __getOwnPropNames = Object.getOwnPropertyNames; | |||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | |||
var __markAsModule = (target) => __defProp(target, "__esModule", {value: true}); | |||
var __export = (target, all) => { | |||
for (var name in all) | |||
__defProp(target, name, {get: all[name], enumerable: true}); | |||
}; | |||
var __exportStar = (target, module2, desc) => { | |||
if (module2 && typeof module2 === "object" || typeof module2 === "function") { | |||
for (let key of __getOwnPropNames(module2)) | |||
if (!__hasOwnProp.call(target, key) && key !== "default") | |||
__defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable}); | |||
} | |||
return target; | |||
}; | |||
var __toModule = (module2) => { | |||
return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2); | |||
}; | |||
__markAsModule(exports); | |||
__export(exports, { | |||
default: () => src_default, | |||
defaultOptions: () => defaultOptions | |||
}); | |||
var import_fs_extra = __toModule(require("fs-extra")); | |||
var import_util = __toModule(require("util")); | |||
var import_path = __toModule(require("path")); | |||
var import_tmp = __toModule(require("tmp")); | |||
var import_postcss2 = __toModule(require("postcss")); | |||
var import_postcss_modules = __toModule(require("postcss-modules")); | |||
var import_less = __toModule(require("less")); | |||
var import_stylus = __toModule(require("stylus")); | |||
var import_resolve_file = __toModule(require("resolve-file")); | |||
const defaultOptions = { | |||
plugins: [], | |||
modules: true, | |||
rootDir: process.cwd(), | |||
sassOptions: {}, | |||
lessOptions: {}, | |||
stylusOptions: {}, | |||
fileIsModule: null | |||
}; | |||
const postCSSPlugin = ({ | |||
plugins = [], | |||
modules = true, | |||
rootDir = process.cwd(), | |||
sassOptions = {}, | |||
lessOptions = {}, | |||
stylusOptions = {}, | |||
fileIsModule | |||
} = defaultOptions) => ({ | |||
name: "postcss2", | |||
setup(build) { | |||
const tmpDirPath = import_tmp.default.dirSync().name, modulesMap = []; | |||
const modulesPlugin = (0, import_postcss_modules.default)({ | |||
generateScopedName: "[name]__[local]___[hash:base64:5]", | |||
...typeof modules !== "boolean" ? modules : {}, | |||
getJSON(filepath, json, outpath) { | |||
const mapIndex = modulesMap.findIndex((m) => m.path === filepath); | |||
if (mapIndex !== -1) { | |||
modulesMap[mapIndex].map = json; | |||
} else { | |||
modulesMap.push({ | |||
path: filepath, | |||
map: json | |||
}); | |||
} | |||
if (typeof modules !== "boolean" && typeof modules.getJSON === "function") | |||
return modules.getJSON(filepath, json, outpath); | |||
} | |||
}); | |||
build.onResolve({filter: /.\.(css|sass|scss|less|styl)$/}, async (args) => { | |||
if (args.namespace !== "file" && args.namespace !== "") | |||
return; | |||
let sourceFullPath = (0, import_resolve_file.default)(args.path); | |||
if (!sourceFullPath) | |||
sourceFullPath = import_path.default.resolve(args.resolveDir, args.path); | |||
const sourceExt = import_path.default.extname(sourceFullPath); | |||
const sourceBaseName = import_path.default.basename(sourceFullPath, sourceExt); | |||
const isModule = fileIsModule ? fileIsModule(sourceFullPath) : sourceBaseName.match(/\.module$/); | |||
const sourceDir = import_path.default.dirname(sourceFullPath); | |||
const watchFiles = [sourceFullPath]; | |||
let tmpFilePath; | |||
if (args.kind === "entry-point") { | |||
const sourceRelDir = import_path.default.relative(import_path.default.dirname(rootDir), import_path.default.dirname(sourceFullPath)); | |||
tmpFilePath = import_path.default.resolve(tmpDirPath, sourceRelDir, `${sourceBaseName}.css`); | |||
await (0, import_fs_extra.ensureDir)(import_path.default.dirname(tmpFilePath)); | |||
} else { | |||
const uniqueTmpDir = import_path.default.resolve(tmpDirPath, uniqueId()); | |||
tmpFilePath = import_path.default.resolve(uniqueTmpDir, `${sourceBaseName}.css`); | |||
} | |||
await (0, import_fs_extra.ensureDir)(import_path.default.dirname(tmpFilePath)); | |||
const fileContent = await (0, import_fs_extra.readFile)(sourceFullPath); | |||
let css = sourceExt === ".css" ? fileContent : ""; | |||
if (sourceExt === ".sass" || sourceExt === ".scss") { | |||
const sassResult = await renderSass({ | |||
...sassOptions, | |||
file: sourceFullPath | |||
}); | |||
css = sassResult.css.toString(); | |||
watchFiles.push(...sassResult.stats.includedFiles); | |||
} | |||
if (sourceExt === ".styl") | |||
css = await renderStylus(new import_util.TextDecoder().decode(fileContent), { | |||
...stylusOptions, | |||
filename: sourceFullPath | |||
}); | |||
if (sourceExt === ".less") | |||
css = (await import_less.default.render(new import_util.TextDecoder().decode(fileContent), { | |||
...lessOptions, | |||
filename: sourceFullPath, | |||
rootpath: import_path.default.dirname(args.path) | |||
})).css; | |||
const result = await (0, import_postcss2.default)(isModule ? [modulesPlugin, ...plugins] : plugins).process(css, { | |||
from: sourceFullPath, | |||
to: tmpFilePath | |||
}); | |||
watchFiles.push(...getPostCssDependencies(result.messages)); | |||
await (0, import_fs_extra.writeFile)(tmpFilePath, result.css); | |||
return { | |||
namespace: isModule ? "postcss-module" : "file", | |||
path: tmpFilePath, | |||
watchFiles, | |||
pluginData: { | |||
originalPath: sourceFullPath | |||
} | |||
}; | |||
}); | |||
build.onLoad({filter: /.*/, namespace: "postcss-module"}, async (args) => { | |||
const mod = modulesMap.find(({path: path2}) => path2 === args?.pluginData?.originalPath), resolveDir = import_path.default.dirname(args.path); | |||
return { | |||
resolveDir, | |||
contents: `import ${JSON.stringify(args.path)}; | |||
export default ${JSON.stringify(mod && mod.map ? mod.map : {})};` | |||
}; | |||
}); | |||
} | |||
}); | |||
function renderSass(options) { | |||
return new Promise((resolve, reject) => { | |||
getSassImpl().render(options, (e, res) => { | |||
if (e) | |||
reject(e); | |||
else | |||
resolve(res); | |||
}); | |||
}); | |||
} | |||
function renderStylus(str, options) { | |||
return new Promise((resolve, reject) => { | |||
import_stylus.default.render(str, options, (e, res) => { | |||
if (e) | |||
reject(e); | |||
else | |||
resolve(res); | |||
}); | |||
}); | |||
} | |||
function getSassImpl() { | |||
let impl = "sass"; | |||
try { | |||
require.resolve("sass"); | |||
} catch { | |||
try { | |||
require.resolve("node-sass"); | |||
impl = "node-sass"; | |||
} catch { | |||
throw new Error('Please install "sass" or "node-sass" package'); | |||
} | |||
} | |||
return require(impl); | |||
} | |||
function getFilesRecursive(directory) { | |||
return (0, import_fs_extra.readdirSync)(directory).reduce((files, file) => { | |||
const name = import_path.default.join(directory, file); | |||
return (0, import_fs_extra.statSync)(name).isDirectory() ? [...files, ...getFilesRecursive(name)] : [...files, name]; | |||
}, []); | |||
} | |||
let idCounter = 0; | |||
function uniqueId() { | |||
return Date.now().toString(16) + (idCounter++).toString(16); | |||
} | |||
function getPostCssDependencies(messages) { | |||
let dependencies = []; | |||
for (const message of messages) { | |||
if (message.type == "dir-dependency") { | |||
dependencies.push(...getFilesRecursive(message.dir)); | |||
} else if (message.type == "dependency") { | |||
dependencies.push(message.file); | |||
} | |||
} | |||
return dependencies; | |||
} | |||
var src_default = postCSSPlugin; |
@@ -256,7 +256,7 @@ copy-anything@^2.0.1: | |||
cross-env@^7.0.3: | |||
version "7.0.3" | |||
resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" | |||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" | |||
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== | |||
dependencies: | |||
cross-spawn "^7.0.1" | |||
@@ -880,7 +880,7 @@ ms@2.1.3, ms@^2.1.1: | |||
resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" | |||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== | |||
nanoid@3.1.20, nanoid@^3.1.20: | |||
nanoid@3.1.20: | |||
version "3.1.20" | |||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz" | |||
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== | |||
@@ -1078,15 +1078,6 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: | |||
resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz" | |||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== | |||
postcss@8.x: | |||
version "8.2.8" | |||
resolved "https://registry.npmjs.org/postcss/-/postcss-8.2.8.tgz" | |||
integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== | |||
dependencies: | |||
colorette "^1.2.2" | |||
nanoid "^3.1.20" | |||
source-map "^0.6.1" | |||
prettier@^2.2.1: | |||
version "2.2.1" | |||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz" | |||