@weapp-tailwindcss/init
Version:
@weapp-tailwindcss/init
106 lines (105 loc) • 4.16 kB
JavaScript
import process from "node:process";
import { logger } from "@weapp-tailwindcss/logger";
import { defu, setValue } from "@weapp-tailwindcss/shared";
import fs from "fs-extra";
import path from "pathe";
//#region src/npm.ts
/**
* @example 'https://registry.npmjs.org'
* @example 'https://registry.npmmirror.com'
*/
function fetchPackage(packageName, options) {
const opts = defu(options, { registry: "https://registry.npmmirror.com" });
return import("npm-registry-fetch").then(({ json }) => {
return json(`/${packageName}`, opts);
});
}
async function getLatestVersionInRange(packageName, versionRange, options) {
const response = await fetchPackage(packageName, options);
return Object.keys(response.versions).filter((version) => version.startsWith(versionRange)).at(-1);
}
const defaultDevDeps = {
"tailwindcss": "3",
"postcss": "8",
"autoprefixer": "10",
"weapp-tailwindcss": "3"
};
async function getDevDepsVersions(options) {
return Object.fromEntries(await Promise.all(Object.entries(defaultDevDeps).map(async (x) => {
return [x[0], `^${await getLatestVersionInRange(...x, options)}`];
})));
}
//#endregion
//#region src/index.ts
async function createContext(options) {
const { cwd, pkgJsonBasename, postcssConfigBasename, tailwindConfigBasename, fetchOptions } = options;
const pkgJsonPath = path.resolve(cwd, pkgJsonBasename);
if (await fs.exists(pkgJsonPath)) {
const pkgJson = await fs.readJson(pkgJsonPath);
return {
pkgJson,
pkgJsonPath,
cwd,
versions: await getDevDepsVersions(fetchOptions),
postcssConfigBasename,
tailwindConfigBasename,
get type() {
return pkgJson.type;
}
};
} else logger.warn("当前目录下不存在 `package.json` 文件,初始化脚本将被跳过,请执行 `npm init` 或手动创建 `package.json` 后重试 ");
}
async function updatePackageJson(ctx) {
for (const [key, value] of Object.entries(ctx.versions)) setValue(ctx.pkgJson, `devDependencies.${key}`, value);
await fs.writeJSON(ctx.pkgJsonPath, ctx.pkgJson, { spaces: 2 });
}
async function touchPostcssConfig(ctx) {
const data = `${ctx.type === "module" ? "export default " : "module.exports = "}{
plugins: {
// Tailwind CSS 由 weapp-tailwindcss 生成模式接管,这里不要再注册 tailwindcss
// 假如框架已经内置了 \`autoprefixer\`,可以去除下一行
autoprefixer: {},
},
}
`;
await fs.writeFile(path.resolve(ctx.cwd, ctx.postcssConfigBasename), data);
}
async function touchTailwindConfig(ctx) {
const data = `/** @type {import('tailwindcss').Config} */
${ctx.type === "module" ? "export default " : "module.exports = "}{
// 这里给出了一份 uni-app /taro 通用示例,具体要根据你自己项目的目录结构进行配置
// 不在 content 包括的文件内,你编写的 class,是不会生成对应的css工具类的
content: ['./public/index.html', './src/**/*.{wxml,html,js,ts,jsx,tsx,vue}'],
// 其他配置项
// ...
corePlugins: {
// 小程序不需要 preflight 和 container,因为这主要是给 h5 的,如果你要同时开发小程序和 h5 端,你应该使用环境变量来控制它
preflight: false,
container: false,
},
}
`;
await fs.writeFile(path.resolve(ctx.cwd, ctx.tailwindConfigBasename), data);
}
function getInitDefaults() {
return {
cwd: process.cwd(),
postcssConfigBasename: "postcss.config.js",
tailwindConfigBasename: "tailwind.config.js",
pkgJsonBasename: "package.json"
};
}
async function init(options) {
const ctx = await createContext(defu(options, getInitDefaults()));
if (ctx) {
await updatePackageJson(ctx);
logger.success("`package.json` 文件修改完成!");
await touchPostcssConfig(ctx);
logger.success("`postcss.config.js` 文件创建完成!");
await touchTailwindConfig(ctx);
logger.success("`tailwind.config.js` 文件创建完成!");
logger.success("`weapp-tailwindcss` 初始化完成!请根据你自定义的需求,更改对应的配置文件(比如 `tailwind.config.js` 中的 `content` 配置)");
}
}
//#endregion
export { createContext, getInitDefaults, init, touchPostcssConfig, touchTailwindConfig, updatePackageJson };