123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- // @ts-check
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- Object.defineProperty(exports, "createProcessor", {
- enumerable: true,
- get: function() {
- return createProcessor;
- }
- });
- const _path = /*#__PURE__*/ _interop_require_default(require("path"));
- const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
- const _postcssloadconfig = /*#__PURE__*/ _interop_require_default(require("postcss-load-config"));
- const _lilconfig = require("lilconfig");
- const _plugins = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/plugins" // Little bit scary, looking at private/internal API
- ));
- const _options = /*#__PURE__*/ _interop_require_default(require("postcss-load-config/src/options" // Little bit scary, looking at private/internal API
- ));
- const _processTailwindFeatures = /*#__PURE__*/ _interop_require_default(require("../../processTailwindFeatures"));
- const _deps = require("./deps");
- const _utils = require("./utils");
- const _sharedState = require("../../lib/sharedState");
- const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../../../resolveConfig.js"));
- const _content = require("../../lib/content.js");
- const _watching = require("./watching.js");
- const _fastglob = /*#__PURE__*/ _interop_require_default(require("fast-glob"));
- const _findAtConfigPath = require("../../lib/findAtConfigPath.js");
- const _log = /*#__PURE__*/ _interop_require_default(require("../../util/log"));
- const _loadconfig = require("../../lib/load-config");
- const _getModuleDependencies = /*#__PURE__*/ _interop_require_default(require("../../lib/getModuleDependencies"));
- function _interop_require_default(obj) {
- return obj && obj.__esModule ? obj : {
- default: obj
- };
- }
- /**
- *
- * @param {string} [customPostCssPath ]
- * @returns
- */ async function loadPostCssPlugins(customPostCssPath) {
- let config = customPostCssPath ? await (async ()=>{
- let file = _path.default.resolve(customPostCssPath);
- // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.1.0/src/index.js
- // @ts-ignore
- let { config ={} } = await (0, _lilconfig.lilconfig)("postcss").load(file);
- if (typeof config === "function") {
- config = config();
- } else {
- config = Object.assign({}, config);
- }
- if (!config.plugins) {
- config.plugins = [];
- }
- return {
- file,
- plugins: (0, _plugins.default)(config, file),
- options: (0, _options.default)(config, file)
- };
- })() : await (0, _postcssloadconfig.default)();
- let configPlugins = config.plugins;
- let configPluginTailwindIdx = configPlugins.findIndex((plugin)=>{
- if (typeof plugin === "function" && plugin.name === "tailwindcss") {
- return true;
- }
- if (typeof plugin === "object" && plugin !== null && plugin.postcssPlugin === "tailwindcss") {
- return true;
- }
- return false;
- });
- let beforePlugins = configPluginTailwindIdx === -1 ? [] : configPlugins.slice(0, configPluginTailwindIdx);
- let afterPlugins = configPluginTailwindIdx === -1 ? configPlugins : configPlugins.slice(configPluginTailwindIdx + 1);
- return [
- beforePlugins,
- afterPlugins,
- config.options
- ];
- }
- function loadBuiltinPostcssPlugins() {
- let postcss = (0, _deps.loadPostcss)();
- let IMPORT_COMMENT = "__TAILWIND_RESTORE_IMPORT__: ";
- return [
- [
- (root)=>{
- root.walkAtRules("import", (rule)=>{
- if (rule.params.slice(1).startsWith("tailwindcss/")) {
- rule.after(postcss.comment({
- text: IMPORT_COMMENT + rule.params
- }));
- rule.remove();
- }
- });
- },
- (0, _deps.loadPostcssImport)(),
- (root)=>{
- root.walkComments((rule)=>{
- if (rule.text.startsWith(IMPORT_COMMENT)) {
- rule.after(postcss.atRule({
- name: "import",
- params: rule.text.replace(IMPORT_COMMENT, "")
- }));
- rule.remove();
- }
- });
- }
- ],
- [],
- {}
- ];
- }
- let state = {
- /** @type {any} */ context: null,
- /** @type {ReturnType<typeof createWatcher> | null} */ watcher: null,
- /** @type {{content: string, extension: string}[]} */ changedContent: [],
- /** @type {ReturnType<typeof load> | null} */ configBag: null,
- contextDependencies: new Set(),
- /** @type {import('../../lib/content.js').ContentPath[]} */ contentPaths: [],
- refreshContentPaths () {
- var _this_context;
- this.contentPaths = (0, _content.parseCandidateFiles)(this.context, (_this_context = this.context) === null || _this_context === void 0 ? void 0 : _this_context.tailwindConfig);
- },
- get config () {
- return this.context.tailwindConfig;
- },
- get contentPatterns () {
- return {
- all: this.contentPaths.map((contentPath)=>contentPath.pattern),
- dynamic: this.contentPaths.filter((contentPath)=>contentPath.glob !== undefined).map((contentPath)=>contentPath.pattern)
- };
- },
- loadConfig (configPath, content) {
- if (this.watcher && configPath) {
- this.refreshConfigDependencies();
- }
- let config = (0, _loadconfig.loadConfig)(configPath);
- let dependencies = (0, _getModuleDependencies.default)(configPath);
- this.configBag = {
- config,
- dependencies,
- dispose () {
- for (let file of dependencies){
- delete require.cache[require.resolve(file)];
- }
- }
- };
- // @ts-ignore
- this.configBag.config = (0, _resolveConfig.default)(this.configBag.config, {
- content: {
- files: []
- }
- });
- // Override content files if `--content` has been passed explicitly
- if ((content === null || content === void 0 ? void 0 : content.length) > 0) {
- this.configBag.config.content.files = content;
- }
- return this.configBag.config;
- },
- refreshConfigDependencies () {
- var _this_configBag;
- _sharedState.env.DEBUG && console.time("Module dependencies");
- (_this_configBag = this.configBag) === null || _this_configBag === void 0 ? void 0 : _this_configBag.dispose();
- _sharedState.env.DEBUG && console.timeEnd("Module dependencies");
- },
- readContentPaths () {
- let content = [];
- // Resolve globs from the content config
- // TODO: When we make the postcss plugin async-capable this can become async
- let files = _fastglob.default.sync(this.contentPatterns.all);
- let checkBroadPattern = (0, _content.createBroadPatternCheck)(this.contentPatterns.all);
- for (let file of files){
- checkBroadPattern(file);
- content.push({
- content: _fs.default.readFileSync(_path.default.resolve(file), "utf8"),
- extension: _path.default.extname(file).slice(1)
- });
- }
- // Resolve raw content in the tailwind config
- let rawContent = this.config.content.files.filter((file)=>{
- return file !== null && typeof file === "object";
- });
- for (let { raw: htmlContent , extension ="html" } of rawContent){
- content.push({
- content: htmlContent,
- extension
- });
- }
- return content;
- },
- getContext ({ createContext , cliConfigPath , root , result , content }) {
- _sharedState.env.DEBUG && console.time("Searching for config");
- var _findAtConfigPath1;
- let configPath = (_findAtConfigPath1 = (0, _findAtConfigPath.findAtConfigPath)(root, result)) !== null && _findAtConfigPath1 !== void 0 ? _findAtConfigPath1 : cliConfigPath;
- _sharedState.env.DEBUG && console.timeEnd("Searching for config");
- if (this.context) {
- this.context.changedContent = this.changedContent.splice(0);
- return this.context;
- }
- _sharedState.env.DEBUG && console.time("Loading config");
- let config = this.loadConfig(configPath, content);
- _sharedState.env.DEBUG && console.timeEnd("Loading config");
- _sharedState.env.DEBUG && console.time("Creating context");
- this.context = createContext(config, []);
- Object.assign(this.context, {
- userConfigPath: configPath
- });
- _sharedState.env.DEBUG && console.timeEnd("Creating context");
- _sharedState.env.DEBUG && console.time("Resolving content paths");
- this.refreshContentPaths();
- _sharedState.env.DEBUG && console.timeEnd("Resolving content paths");
- if (this.watcher) {
- _sharedState.env.DEBUG && console.time("Watch new files");
- this.watcher.refreshWatchedFiles();
- _sharedState.env.DEBUG && console.timeEnd("Watch new files");
- }
- for (let file of this.readContentPaths()){
- this.context.changedContent.push(file);
- }
- return this.context;
- }
- };
- async function createProcessor(args, cliConfigPath) {
- var _args_content;
- let postcss = (0, _deps.loadPostcss)();
- let input = args["--input"];
- let output = args["--output"];
- let includePostCss = args["--postcss"];
- let customPostCssPath = typeof args["--postcss"] === "string" ? args["--postcss"] : undefined;
- let [beforePlugins, afterPlugins, postcssOptions] = includePostCss ? await loadPostCssPlugins(customPostCssPath) : loadBuiltinPostcssPlugins();
- if (args["--purge"]) {
- _log.default.warn("purge-flag-deprecated", [
- "The `--purge` flag has been deprecated.",
- "Please use `--content` instead."
- ]);
- if (!args["--content"]) {
- args["--content"] = args["--purge"];
- }
- }
- var _args_content_split;
- let content = (_args_content_split = (_args_content = args["--content"]) === null || _args_content === void 0 ? void 0 : _args_content.split(/(?<!{[^}]+),/)) !== null && _args_content_split !== void 0 ? _args_content_split : [];
- let tailwindPlugin = ()=>{
- return {
- postcssPlugin: "tailwindcss",
- async Once (root, { result }) {
- _sharedState.env.DEBUG && console.time("Compiling CSS");
- await (0, _processTailwindFeatures.default)(({ createContext })=>{
- console.error();
- console.error("Rebuilding...");
- return ()=>{
- return state.getContext({
- createContext,
- cliConfigPath,
- root,
- result,
- content
- });
- };
- })(root, result);
- _sharedState.env.DEBUG && console.timeEnd("Compiling CSS");
- }
- };
- };
- tailwindPlugin.postcss = true;
- let plugins = [
- ...beforePlugins,
- tailwindPlugin,
- !args["--minify"] && _utils.formatNodes,
- ...afterPlugins,
- !args["--no-autoprefixer"] && (0, _deps.loadAutoprefixer)(),
- args["--minify"] && (0, _deps.loadCssNano)()
- ].filter(Boolean);
- /** @type {import('postcss').Processor} */ // @ts-ignore
- let processor = postcss(plugins);
- async function readInput() {
- // Piping in data, let's drain the stdin
- if (input === "-") {
- return (0, _utils.drainStdin)();
- }
- // Input file has been provided
- if (input) {
- return _fs.default.promises.readFile(_path.default.resolve(input), "utf8");
- }
- // No input file provided, fallback to default at-rules
- return "@tailwind base; @tailwind components; @tailwind utilities";
- }
- async function build() {
- let start = process.hrtime.bigint();
- return readInput().then((css)=>processor.process(css, {
- ...postcssOptions,
- from: input,
- to: output
- })).then((result)=>{
- if (!state.watcher) {
- return result;
- }
- _sharedState.env.DEBUG && console.time("Recording PostCSS dependencies");
- for (let message of result.messages){
- if (message.type === "dependency") {
- state.contextDependencies.add(message.file);
- }
- }
- _sharedState.env.DEBUG && console.timeEnd("Recording PostCSS dependencies");
- // TODO: This needs to be in a different spot
- _sharedState.env.DEBUG && console.time("Watch new files");
- state.watcher.refreshWatchedFiles();
- _sharedState.env.DEBUG && console.timeEnd("Watch new files");
- return result;
- }).then((result)=>{
- if (!output) {
- process.stdout.write(result.css);
- return;
- }
- return Promise.all([
- (0, _utils.outputFile)(result.opts.to, result.css),
- result.map && (0, _utils.outputFile)(result.opts.to + ".map", result.map.toString())
- ]);
- }).then(()=>{
- let end = process.hrtime.bigint();
- console.error();
- console.error("Done in", (end - start) / BigInt(1e6) + "ms.");
- }).then(()=>{}, (err)=>{
- // TODO: If an initial build fails we can't easily pick up any PostCSS dependencies
- // that were collected before the error occurred
- // The result is not stored on the error so we have to store it externally
- // and pull the messages off of it here somehow
- // This results in a less than ideal DX because the watcher will not pick up
- // changes to imported CSS if one of them caused an error during the initial build
- // If you fix it and then save the main CSS file so there's no error
- // The watcher will start watching the imported CSS files and will be
- // resilient to future errors.
- if (state.watcher) {
- console.error(err);
- } else {
- return Promise.reject(err);
- }
- });
- }
- /**
- * @param {{file: string, content(): Promise<string>, extension: string}[]} changes
- */ async function parseChanges(changes) {
- return Promise.all(changes.map(async (change)=>({
- content: await change.content(),
- extension: change.extension
- })));
- }
- if (input !== undefined && input !== "-") {
- state.contextDependencies.add(_path.default.resolve(input));
- }
- return {
- build,
- watch: async ()=>{
- state.watcher = (0, _watching.createWatcher)(args, {
- state,
- /**
- * @param {{file: string, content(): Promise<string>, extension: string}[]} changes
- */ async rebuild (changes) {
- let needsNewContext = changes.some((change)=>{
- var _state_configBag;
- return ((_state_configBag = state.configBag) === null || _state_configBag === void 0 ? void 0 : _state_configBag.dependencies.has(change.file)) || state.contextDependencies.has(change.file);
- });
- if (needsNewContext) {
- state.context = null;
- } else {
- for (let change of (await parseChanges(changes))){
- state.changedContent.push(change);
- }
- }
- return build();
- }
- });
- await build();
- }
- };
- }
|