@@ -3,5 +3,4 @@ build | |||||
yarn-error.log | yarn-error.log | ||||
test/dist | test/dist | ||||
package-lock.json | package-lock.json | ||||
dist | |||||
test/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: | cross-env@^7.0.3: | ||||
version "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== | integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== | ||||
dependencies: | dependencies: | ||||
cross-spawn "^7.0.1" | 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" | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" | ||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== | ||||
nanoid@3.1.20, nanoid@^3.1.20: | |||||
nanoid@3.1.20: | |||||
version "3.1.20" | version "3.1.20" | ||||
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz" | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz" | ||||
integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== | 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" | resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz" | ||||
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== | 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: | prettier@^2.2.1: | ||||
version "2.2.1" | version "2.2.1" | ||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz" | resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz" | ||||