bascik
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseBascik
Bascik
Bascik is a build tool for HTML components. It expands custom tags such as into the matching component file, scopes the component's CSS, IDs, classes, and scripts, and writes plain HTML pages to . It adds zero JavaScript: every script in the output is one you wrote.
<site-nav />dist/It is not a framework. There is no virtual DOM, reactive state, client router, template language, Shadow DOM, or runtime. Write HTML, CSS, and TypeScript (stripped to plain JavaScript), and let Bascik do the isolation at build time.
Bascik 是一个 HTML 组件构建工具。它会将 等自定义标签展开为匹配的组件文件,对组件的 CSS、ID、class 和 script 进行作用域隔离,并将普通 HTML 页面写入 。它不会添加任何 JavaScript:输出中的每个 script 都是你自己编写的。
<site-nav />dist/它不是框架。没有虚拟 DOM、响应式状态、客户端 router、模板语言、Shadow DOM 或 runtime。编写 HTML、CSS 和 TypeScript(剥离为纯 JavaScript),让 Bascik 在构建时完成隔离。
Pages read like a list of tags
页面就像一组标签列表
Write pages as a list of component tags, not big blocks of HTML:
html
<body>
<site-header />
<main id="main">
<home-hero />
<pricing-section>
<plan-card data-bascik-prop-name="Home" data-bascik-prop-price="$49" />
<plan-card data-bascik-prop-name="Cafe" data-bascik-prop-price="$129" />
</pricing-section>
<faq-list />
</main>
<site-footer />
</body>- Split a section into a component when it has a job you can name (pricing, reviews, signup form), when its markup repeats, or when the page is no longer readable at a glance.
- Do not split a piece that only makes sense inside its parent, that would need a prop passed through a component that does not use it, or that is a tiny wrapper used once. Use a slot, or keep the parent whole.
- Write each fact once. An address, opening hours, a price, or a phone number lives in one component or one data file, never typed into several. A fact several components show goes in ; data only one component renders (its FAQ entries, its plans) lives in that component's folder (rule 17). A value that is the same on every page, such as the brand name, belongs inside the component, not passed as a prop on every page. A heading group (eyebrow, heading, intro) that repeats across sections is a
src/lib/site.tscomponent with props.<section-head>
Small named files are easier for people and agents to read and change, and each is a boundary for its CSS, IDs, and script. It is a balance: the skill has the detailed guidance with good and bad examples, and checks it.
bascik-componentsscripts/audit-components.mjs像编写组件标签列表一样编写页面,而不是堆砌大段 HTML:
html
<body>
<site-nav />
<main id="main">
<home-hero />
<pricing-section>
<plan-card data-bascik-prop-name="Home" data-bascik-prop-price="$49" />
<plan-card data-bascik-prop-name="Cafe" data-bascik-prop-price="$129" />
</pricing-section>
<faq-list />
</main>
<site-footer />
</body>- 当某个区块承担了可以明确命名的职责(pricing、reviews、signup form)、markup 出现重复,或者页面已经无法一眼读懂时,将其拆分为组件。
- 如果某部分只有放在父组件中才有意义、需要把 prop 传给一个根本不会使用它的组件,或者只是仅使用一次的小型 wrapper,就不要拆分。使用 slot,或者保留完整的父组件。
- 每个事实只编写一次。 地址、营业时间、价格或电话号码应只存在于一个组件或一个数据文件中,绝不能重复输入。一个事实需要由多个组件展示时,将它放在 ;只由一个组件渲染的数据(FAQ 条目、套餐等)应放在该组件的文件夹中(规则 17)。每个页面都相同的值(例如品牌名称)应放在组件内部,而不是在每个页面上都作为 prop 传递。重复出现的标题组(eyebrow、heading、intro)应做成带 props 的
src/lib/site.ts组件。<section-head>
小型且命名清晰的文件更便于开发者和 Agent 阅读与修改,每个文件也是其 CSS、ID 和 script 的隔离边界。这需要权衡: skill 提供了包含优秀与糟糕示例的详细指导, 会对此进行检查。
bascik-componentsscripts/audit-components.mjsTypeScript by default
默认使用 TypeScript
Write all new code in TypeScript. Use JavaScript only when the person asks for it. When refactoring TypeScript, keep it TypeScript and carry the types across.
- Browser code goes in a component's companion (
name.ts) or an inline<script src="name.ts">. Bascik strips the types with Node's strip-only mode, so it works with no setup. Use erasable syntax only: annotations, interfaces,<script type="text/typescript">,as, and!.import type, namespaces with code, and parameter properties fail the build. A plainenumis JavaScript. A page's own<script>is compiled and inlined too; a classic one with<script src="x.ts">ordeferfails the build (inline scripts ignore them), so drop the attribute or mark itasync. Atype="module"type="module"script is inlined, not bundled: importing.ts(or any relative,./util.tsor@/path) fails the build, so bundle it with esbuild or import a published.tsURL./js/*.js - Build, routes, server, and stream scripts are TypeScript with a
.tsor a tag markedsrc=(type="text/typescript"). Bascik strips them the same way before they run, and compiles them when the page builds, so a syntax error or<script data-bascik-server type="text/typescript">fails the build with file:line:column; an unmarked block is JavaScript.enum - blocks are type checked in the editor (the VS Code extension or
type="text/typescript", with hover, definition and completion for imports) and, opted in, by@bascik/language-server.bascik --check --typescript - Node code is too: helpers and data modules,
.tsroutes,src/api/scripts, andpipeline.exec. Node strips their types. Keep eachbascik.config.tsblock to a few lines that import typed helpers:data-bascik-*for a module in the component's own folder,./faqs.tsfor one several pages share (rule 17). A helper that returns markup builds it with@/lib/posts.tsfromhtmland declares@bascik/bascik/htmlas its return type (rule 15).SafeHtml - esbuild is the option for full TypeScript (, decorators, an older browser target):
enum, then setnpm install -D esbuildto an esbuild transform. Browser code that imports npm packages needs esbuild too, as ascripts.typescriptstep that bundles it intopipeline.exec.dist/
ts
// bascik.config.ts (illustrative: esbuild as the browser TypeScript compiler)
import { defineConfig } from "@bascik/bascik/config";
import { transform } from "esbuild";
export default defineConfig({
scripts: {
typescript: async (code, { sourcePath }) => {
const result = await transform(code, {
loader: "ts",
target: "es2020",
sourcefile: sourcePath,
});
return result.code;
},
},
});Read , , and before going beyond erasable syntax.
/scoped-javascript#typescript-in-component-scripts/configuration#scriptstypescript/how-to/bundling-npm-packagesCode in this skill is illustrative. Adapt tag names, paths, and values to the project instead of copying example names literally.
所有新代码都使用 TypeScript。只有在用户明确要求时才使用 JavaScript。重构 TypeScript 时,继续保留 TypeScript,并让类型贯穿整个重构。
- 浏览器代码应放在组件的配套文件 (
name.ts)或内联<script src="name.ts">中。Bascik 使用 Node 的仅剥离模式移除类型,因此无需任何配置即可工作。仅使用可擦除语法:类型标注、interface、<script type="text/typescript">、as和!。import type、包含代码的 namespace 和参数属性会导致构建失败。普通enum是 JavaScript。页面自身的<script>也会被编译并内联;带有<script src="x.ts">或defer的传统 script 会导致构建失败(内联 script 会忽略它们),因此应移除该属性或标记为async。type="module"的type="module"script 会被内联而不会被打包:导入.ts(或任何相对路径、./util.ts或@/路径)都会导致构建失败,因此应使用 esbuild 打包,或导入已发布的.tsURL。/js/*.js - 构建、路由、server 和 stream script 应使用带 的
.ts或标记为src=的标签(type="text/typescript")。Bascik 会以相同方式剥离类型,并在页面构建时编译它们,因此语法错误或<script data-bascik-server type="text/typescript">会以 file:line:column 的形式导致构建失败;未标记的代码块是 JavaScript。enum - 代码块会在编辑器中进行类型检查(VS Code 扩展或
type="text/typescript",支持悬停、定义和导入补全),也可以选择通过@bascik/language-server进行检查。bascik --check --typescript - Node 代码也使用 :helper、数据模块、
.ts路由、src/api/script 和pipeline.exec。Node 会剥离它们的类型。让每个bascik.config.ts代码块保持简短,并导入带类型的 helper:组件自己文件夹中的模块使用data-bascik-*,多个页面共享的模块使用./faqs.ts(规则 17)。返回 markup 的 helper 应使用@/lib/posts.ts中的@bascik/bascik/html构造 markup,并将返回类型声明为html(规则 15)。SafeHtml - 完整 TypeScript 功能可使用 esbuild(、decorator、较旧的浏览器 target):运行
enum,然后将npm install -D esbuild设置为 esbuild transform。导入 npm 包的浏览器代码也需要 esbuild,作为scripts.typescript步骤打包到pipeline.exec中。dist/
ts
// bascik.config.ts (illustrative: esbuild as the browser TypeScript compiler)
import { defineConfig } from "@bascik/bascik/config";
import { transform } from "esbuild";
export default defineConfig({
scripts: {
typescript: async (code, { sourcePath }) => {
const result = await transform(code, {
loader: "ts",
target: "es2020",
sourcefile: sourcePath,
});
return result.code;
},
},
});在超出可擦除语法范围之前,请阅读 、 和 。
/scoped-javascript#typescript-in-component-scripts/configuration#scriptstypescript/how-to/bundling-npm-packages本 skill 中的代码仅作示例。应根据项目调整标签名称、路径和值,不要逐字照抄示例名称。
Recognize a Bascik project
识别 Bascik 项目
- depends on
package.json, or the root has@bascik/bascik/bascik.config.ts, or there arebascik.config.jsfiles under.html.src/components/ - Node.js 24.21 or newer (26, the current LTS, recommended). Node runs files natively and Bascik strips browser TypeScript, so no TypeScript build step exists.
.ts - Standard scripts: (
npm run dev),bascik(npm run build),bascik --build(npm run lint).bascik --checkis always plaindev, also in a Cloudflare or Netlify project: never rewrite it tobascik,wrangler dev, ornetlify dev. The host's runtime gets its own script (bascik --target ...,dev:cloudflare); see thedev:netlifyskill, Deploy.bascik-config
- 依赖
package.json,或根目录包含@bascik/bascik/bascik.config.ts,或bascik.config.js下存在src/components/文件。.html - Node.js 24.21 或更高版本(推荐使用 26,即当前 LTS)。Node 原生运行 文件,Bascik 会剥离浏览器 TypeScript,因此不需要 TypeScript 构建步骤。
.ts - 标准 scripts:(
npm run dev)、bascik(npm run build)、bascik --build(npm run lint)。bascik --check始终使用普通的dev,在 Cloudflare 或 Netlify 项目中也是如此:绝不要改写为bascik、wrangler dev或netlify dev。host 的 runtime 应使用单独的 script(bascik --target ...、dev:cloudflare);参见dev:netlifyskill 的 Deploy 部分。bascik-config
Project layout
项目布局
text
src/
components/ component templates; the file name is the tag name
site-nav/
site-nav.html <site-nav>
site-nav.css optional companion stylesheet, scoped to site-nav
site-nav.ts optional companion script, loaded with <script src="site-nav.ts">
links.ts data or a helper only site-nav uses, imported with ./links.ts
pages/ one .html file per URL, plus public assets
index.html /
about.html /about
blog/post.html /blog/post
404.html served for unknown routes
css/styles.css copied to dist/css/styles.css (global, unscoped)
lib/ modules several components or pages share (import with @/lib/...)
api/ optional API route handlers in .ts (bascik --server only)
dist/ compiled output, never edited by hand, never committedtext
src/
components/ component templates; the file name is the tag name
site-nav/
site-nav.html <site-nav>
site-nav.css optional companion stylesheet, scoped to site-nav
site-nav.ts optional companion script, loaded with <script src="site-nav.ts">
links.ts data or a helper only site-nav uses, imported with ./links.ts
pages/ one .html file per URL, plus public assets
index.html /
about.html /about
blog/post.html /blog/post
404.html served for unknown routes
css/styles.css copied to dist/css/styles.css (global, unscoped)
lib/ modules several components or pages share (import with @/lib/...)
api/ optional API route handlers in .ts (bascik --server only)
dist/ compiled output, never edited by hand, never committedWrite a component
编写组件
Default pattern: above the markup, markup in the middle, a TypeScript below. Give every element a script must control an and find it with , and put a on the root and on each control (rule 16).
<style><script>idgetElementByIddata-testidhtml
<!-- src/components/like-button/like-button.html -->
<style>
.like {
padding: 0.5rem 1rem;
border-radius: 6px;
}
.like.active {
background: #d3ff8d;
}
</style>
<button class="like" id="btn" type="button" data-testid="like-button">
<span data-bascik-prop-label>Like</span>
</button>
<script type="text/typescript">
const btn = document.getElementById("btn") as HTMLButtonElement;
btn.addEventListener("click", () => btn.classList.toggle("active"));
</script>html
<!-- src/pages/index.html -->
<like-button data-bascik-prop-label="Like this post" />
<like-button data-bascik-prop-label="Like this comment" />Bascik strips the types, rewrites to , gives each instance its own (), rewrites the string and the class to match, and wraps the script in an IIFE. For a longer script, move it to beside the template and load it with . Both buttons work independently. To see the exact output, run .
.like.bascik__like-button__likeidbascik__like-button__<instance>__btngetElementByIdclassListlike-button.ts<script src="like-button.ts"></script>scripts/preview.mjsNew components are picked up by the running dev server automatically; no restart is needed.
默认模式是: 放在上方,markup 放在中间,TypeScript 放在下方。为每个需要由 script 控制的元素提供 并使用 查找,同时在根元素和每个控件上添加 (规则 16)。
<style><script>idgetElementByIddata-testidhtml
<!-- src/components/like-button/like-button.html -->
<style>
.like {
padding: 0.5rem 1rem;
border-radius: 6px;
}
.like.active {
background: #d3ff8d;
}
</style>
<button class="like" id="btn" type="button" data-testid="like-button">
<span data-bascik-prop-label>Like</span>
</button>
<script type="text/typescript">
const btn = document.getElementById("btn") as HTMLButtonElement;
btn.addEventListener("click", () => btn.classList.toggle("active"));
</script>html
<!-- src/pages/index.html -->
<like-button data-bascik-prop-label="Like this post" />
<like-button data-bascik-prop-label="Like this comment" />Bascik 会剥离类型,将 重写为 ,为每个实例生成独立的 (),重写 中的字符串和 class 以保持一致,并将 script 包裹在 IIFE 中。对于更长的 script,将其移到模板旁边的 ,并使用 加载。两个按钮都能独立工作。运行 可以查看精确输出。
.like.bascik__like-button__likeidbascik__like-button__<instance>__btngetElementByIdclassListlike-button.ts<script src="like-button.ts"></script>scripts/preview.mjs运行中的 dev server 会自动识别新组件,无需重启。
Rules (must follow)
规则(必须遵守)
- Concise, lowercase component names. Name the job, not the app: , not
not-found;shop-not-found, notnavigation. Use hyphens between words, never underscores. A non-native single word works because Bascik expands it before the browser sees it, although the CLI/editor recommend hyphens for future compatibility. Never use a native HTML, SVG, or MathML element name, including obsolete names (shop-nav,nav,dialog,path,mi); usekeygen,navigation, orsite-headerinstead. Names must be unique across every component root. Seesite-footer./components#component-naming-and-hyphens - Per-instance targeting uses . Use
id(orgetElementById) for elements a script controls.getElementsByNamereturns the first instance on the page, so the other instances look broken.querySelector('.cls') - Order: above the markup,
<style>below it.<script> - Props carry text only. values are HTML-escaped strings. Pass markup or nested components through slots (
data-bascik-prop-*).data-bascik-slot - Self-close components that take no slot content: ,
<site-head />.<site-footer /> - HTML and CSS first. Reach for JavaScript only when HTML and CSS cannot do the job cleanly (,
<details>,<dialog>,:has()cover a lot).popover - Semantic HTML. Pick the element the HTML standard defines for the job, because Bascik ships exactly the markup you write: a component's root is the semantic element itself (renders a
<site-nav>, a review an<nav>, a form a<article>), not a wrapper<form>;<div>for actions and<button type="button">for navigation, never a clickable<a href>or<div>; one<span>and one<main>per page with no skipped heading levels; a<h1>for every control;<label>on every image; nativealt,<details>, and<dialog>before ARIA or JavaScript. The checklist with spec links:popover.read-doc.mjs /component-best-practices#use-htmls-elements - Runtime state in attributes. Toggle
data-and styledata-state="open"; anchor attribute selectors on a scoped class..panel[data-state="open"] - Zero config. Do not create unless a requirement differs from a default, and never put
bascik.config.tsin it. See thesiteUrlskill.bascik-config - Never write generated files into . Generated output goes to
src/(dist/) from an existingBASCIK_OUT_DIRscript.pipeline.exec - Client scripts are not bundled. Bare imports such as fail in the browser. They work only in Node-side scripts (
import x from 'pkg',data-bascik-build). Bundle browser packages with esbuild (data-bascik-server).read-doc.mjs /how-to/bundling-npm-packages - Pages are lists of tags. Shared tags, the header, the footer, and every section with a nameable job become components (
<head>,<site-head />,<site-header />,<pricing-section />). Pages keep their own<site-footer />,<html>, and<head>. Balance it: no tiny single-use wrappers and no props passed through components that do not use them.<body> - Script directives are exclusive. One tag takes at most one of
<script>,data-bascik-build,data-bascik-build-once,data-bascik-routes,data-bascik-server.data-bascik-streamruns once per file with no page context.data-bascik-build-once - TypeScript by default. New browser and Node code is TypeScript (see "TypeScript by default" above). Use JavaScript only when the person asks for it.
- Every script and helper builds markup with . Any build, build-once, routes, server or stream script, API route, and any
htmlhelper that returns markup (in.tsor beside a component) doessrc/lib/and returnsimport { html } from "@bascik/bascik/html": it escapes each value for where it lands, turnshtml`<p>${value}</p>`URLs intojavascript:, and throws where escaping cannot help. Useabout:invalidonly for markup the project wrote and trusts or sanitized CMS HTML,raw()for JSON-LD, andjson()oresc()where a string is built withoutsafeUrl(). Never write your own escaper (html, anescapeHtmlreplace chain) and never interpolate data into a plain template string. Give a URL attribute one hole: build the URL in code first (&, thenconst href = `${siteUrl}${path}`), becausehref="${href}"refuses two holes before the URL's firsthtml(/) so that two values cannot spellurl-scheme-splittogether. A browser script cannot import it: setjavascript:there. See thetextContentskill.bascik-scripts - A on what a test needs. Every component root gets
data-testid, and every interactive part (a button, an input, select, or textarea, adata-testid="<component-name>", a link a script handles, an element with an ARIA widget role or<summary>) getstabindex="0". Forms, dialogs, and landmarks (data-testid="<component-name>-<part>",<main>, the page's<nav>and<header>) get one too. Bascik never scopes or hashes<footer>, sodata-testidmatches in a production build where classes and ids are hashed. Instances share their ids: a test picks one withgetByTestId(...), or the page names one with.filter({ hasText })on the usage tag, which replaces the root's. Never put request or random data in a test id, and keep existing hooks (data-testid,data-test,data-cy) when migrating.data-qaadds the root's, andscripts/new-component.mjslists the gaps. Seescripts/verify.mjs.read-doc.mjs /testing/e2e-testing - Colocate what one component or page uses. A module (data, helper, types) that one component uses lives in that component's folder, with its tests, and is imported with (
./). Content lives with the component that renders it: a page that also needs it, for JSON-LD say, imports it from there (import { faqs } from "./faqs.ts"). A module only one page uses sits beside that page as a@/components/faq-list/faqs.tsfile (the pages folder publishes a.tsor.jsonfile as a public asset, never a.jsone). Only modules several components or pages share, or that config, exec scripts, or API routes also import, go in.ts. Files in component and page folders are watched already;src/lib/needssrc/lib/.pipeline.watchPathsreports ascripts/audit-components.mjsmodule with one user (src/lib/).single-use-module
- 组件名称应简洁且使用小写。 根据职责命名,而不是根据应用命名:使用 ,而不是
not-found;使用shop-not-found,而不是navigation。单词之间使用连字符,绝不使用下划线。非原生单词可以使用,因为 Bascik 会在浏览器看到之前将其展开,不过 CLI/editor 建议使用连字符以保持未来兼容性。绝不要使用原生 HTML、SVG 或 MathML 元素名,包括过时名称(shop-nav、nav、dialog、path、mi);应改用keygen、navigation或site-header。所有组件根元素的名称必须保持唯一。参见site-footer。/components#component-naming-and-hyphens - 按实例定位时使用 。 对 script 控制的元素使用
id(或getElementById)。getElementsByName只返回页面上的第一个实例,因此其他实例会看起来像是失效了。querySelector('.cls') - 顺序: 放在 markup 上方,
<style>放在下方。<script> - Props 只承载文本。 的值是经过 HTML 转义的字符串。通过 slots 传递 markup 或嵌套组件(
data-bascik-prop-*)。data-bascik-slot - 不接受 slot 内容的组件应自闭合: 、
<site-head />。<site-footer /> - 优先使用 HTML 和 CSS。 只有在 HTML 和 CSS 无法干净完成任务时才使用 JavaScript(、
<details>、<dialog>、:has()已能覆盖很多场景)。popover - 使用语义化 HTML。 根据 HTML 标准为职责选择元素,因为 Bascik 输出的正是你编写的 markup:组件根元素本身就是语义元素(渲染为
<site-nav>,review 渲染为<nav>,form 渲染为<article>),而不是使用<form>wrapper;操作用<div>,导航用<button type="button">,绝不让<a href>或<div>可点击;每页使用一个<span>和一个<main>,且不跳过标题级别;每个控件都有<h1>;每张图片都有<label>;优先使用原生alt、<details>和<dialog>,然后才考虑 ARIA 或 JavaScript。检查清单及规范链接:popover。read-doc.mjs /component-best-practices#use-htmls-elements - Runtime 状态使用 属性。 切换
data-,并使用data-state="open"设置样式;在 scoped class 上使用 anchor attribute selector。.panel[data-state="open"] - 零配置。 除非需求与默认行为不同,否则不要创建 ,并且绝不把
bascik.config.ts放入其中。参见siteUrlskill。bascik-config - 绝不把生成文件写入 。 生成输出应通过已有的
src/script 写入pipeline.exec(dist/)。BASCIK_OUT_DIR - 客户端 script 不会被打包。 浏览器端的裸导入(例如 )会失败。它们只适用于 Node 端 script(
import x from 'pkg'、data-bascik-build)。使用 esbuild 打包浏览器依赖(data-bascik-server)。read-doc.mjs /how-to/bundling-npm-packages - 页面是标签列表。 共享的 标签、header、footer,以及每个具有明确职责的区块都应成为组件(
<head>、<site-head />、<site-header />、<pricing-section />)。页面保留自己的<site-footer />、<html>和<head>。保持平衡:不要创建微型单用途 wrapper,也不要把 props 传递给根本不会使用它们的组件。<body> - Script 指令互斥。 一个 标签最多只能使用
<script>、data-bascik-build、data-bascik-build-once、data-bascik-routes、data-bascik-server中的一个。data-bascik-stream每个文件只运行一次,且没有页面上下文。data-bascik-build-once - 默认使用 TypeScript。 所有新的浏览器端和 Node 端代码都使用 TypeScript(参见上文“默认使用 TypeScript”)。只有在用户要求时才使用 JavaScript。
- 每个 script 和 helper 都使用 构造 markup。 任何 build、build-once、routes、server 或 stream script、API route,以及任何返回 markup 的
htmlhelper(位于.ts或组件旁)都要src/lib/,并返回import { html } from "@bascik/bascik/html":它会针对每个值最终落入的位置进行转义,将html`<p>${value}</p>`URL 转换为javascript:,并在无法通过转义解决问题时抛出异常。仅对项目自行编写且可信的 markup 或经过清理的 CMS HTML 使用about:invalid,对 JSON-LD 使用raw(),对未通过json()构建的字符串使用html或esc()。绝不要自行编写 escaper(safeUrl()、替换escapeHtml的链式处理),也绝不要把数据插入普通模板字符串。URL 属性只留一个 hole:先在代码中构建 URL(&),然后使用const href = `${siteUrl}${path}`,因为href="${href}"会拒绝在 URL 第一个html之前出现两个 hole,从而避免两个值拼成/。浏览器 script 无法导入它:请在那里设置javascript:。参见textContentskill。bascik-scripts - 测试所需元素都要有 。 每个组件根元素都要有
data-testid,每个交互部分(button、input、select、textarea、data-testid="<component-name>"、由 script 处理的链接、带 ARIA widget role 或<summary>的元素)都要有tabindex="0"。表单、dialog 和 landmarks(data-testid="<component-name>-<part>"、<main>、页面的<nav>和<header>)也要添加。Bascik 不会对<footer>进行作用域处理或哈希,因此即使 class 和 id 在生产构建中经过哈希,data-testid仍然可以匹配。多个实例会共享 id:测试可以通过getByTestId(...)选择其中一个,或者在页面的使用标签上设置.filter({ hasText })来命名某个实例,该值会替换根元素上的值。测试 id 中绝不要包含请求数据或随机数据,迁移时还应保留已有测试钩子(data-testid、data-test、data-cy)。data-qa会为根元素添加测试 id,scripts/new-component.mjs会列出缺失项。参见scripts/verify.mjs。read-doc.mjs /testing/e2e-testing - 将仅由一个组件或页面使用的内容放在一起。 仅由一个组件使用的模块(数据、helper、类型)应放在该组件的文件夹中,与测试放在一起,并通过 导入(
./)。内容应与渲染它的组件放在一起:如果页面也需要该内容,例如用于 JSON-LD,就从组件目录导入(import { faqs } from "./faqs.ts")。仅由一个页面使用的模块应作为@/components/faq-list/faqs.ts文件放在页面旁(pages 文件夹会将.ts或.json文件作为公共资产发布,但绝不会发布.js文件)。只有多个组件或页面共享的模块,或者 config、exec script 和 API route 也会导入的模块,才应放入.ts。组件和页面文件夹中的文件已经被监听;src/lib/需要配置src/lib/。pipeline.watchPaths会报告只有一个使用者的scripts/audit-components.mjs模块(src/lib/)。single-use-module
Slots, props, and attributes
Slots、Props 和属性
| Need | Component template | Usage site |
|---|---|---|
| Default slot (rich HTML) | | |
| Named slot | | |
| Text prop | | |
| Prop into an attribute | | |
| Forward attributes | (nothing) | |
Pass props as on the usage tag. A plain attribute such as is not a prop: it is forwarded to the root element and the prop keeps its default. A forwarded attribute the root already has keeps the root's value, except : the usage tag's replaces it, so a page can name one instance. The slot element itself is replaced by the content, so named-slot wrappers disappear: wrap headings and links in a rather than putting the attribute on the or . Details: , , .
data-bascik-prop-<name>="..."label="..."data-testid<div data-bascik-slot="x"><h1><a>read-doc.mjs /slots/props/attribute-inheritance| 需求 | 组件模板 | 使用位置 |
|---|---|---|
| 默认 slot(丰富 HTML) | | |
| 命名 slot | | 在标签内部使用 |
| 文本 prop | | |
| 将 prop 放入 attribute | | |
| 转发属性 | (无) | |
在使用标签上通过 传递 props。普通 attribute(例如 )不是 prop:它会被转发到根元素,而 prop 会保留默认值。根元素已经存在的转发属性会保留根元素的值,但 除外:使用标签上的值会替换它,因此页面可以命名某个实例。slot 元素本身会被内容替换,因此命名 slot 的 wrapper 会消失:请将 heading 和 link 包装在 中,而不是直接在 或 上设置该 attribute。详情参见 、、。
data-bascik-prop-<name>="..."label="..."data-testid<div data-bascik-slot="x"><h1><a>read-doc.mjs /slots/props/attribute-inheritanceScript tags at a glance
Script 标签一览
| Tag | Runs | Use for |
|---|---|---|
| Browser | Component and page behavior (scoped, IIFE-wrapped) |
| Node, at build time | Markup from files, Markdown, APIs; output replaces the tag |
| Node, once per file | Markup shared by every use of a component or every route of a template |
| Node, at build time | Expanding |
| Node, per request | Personalized markup (needs |
| Node, per request, streamed | Slow per-request blocks that should not delay the page shell |
Node-side scripts export a default function that returns an HTML string. Component tags in that HTML render, at build time and, from server and stream scripts, per request. Details are in the skill.
bascik-scripts| 标签 | 运行方式 | 用途 |
|---|---|---|
| 浏览器 | 组件和页面行为(作用域隔离、IIFE 包裹) |
| Node,在构建时 | 来自文件、Markdown、API 的 markup;输出会替换该标签 |
| Node,每个文件运行一次 | 组件的每次使用或模板的每个路由共用的 markup |
| Node,在构建时 | 将 |
| Node,每次请求 | 个性化 markup(需要 |
| Node,每次请求,流式传输 | 不应延迟页面外壳的慢速单请求代码块 |
Node 端 script 导出一个返回 HTML 字符串的默认函数。其 HTML 中的组件标签会在构建时渲染;从 server 和 stream script 渲染时,则在每次请求中渲染。详情参见 skill。
bascik-scriptsCLI
CLI
sh
bascik # dev server at http://localhost:8080 with live reload and watch
bascik --build # production build to dist/ (HTML, CSS, JS, and identifier minification on)
bascik --build --only "blog/**" # rebuild matching pages without cleaning dist/
bascik --server # serve a built dist/ (needed for server/stream scripts and API routes)
bascik --check # project checks, plus the per-file checks when @bascik/language-server is installed
bascik --check --fix # also rewrite fixable findings (needs @bascik/language-server)
bascik add <package> # copy components from an installed npm package into src/components/
bascik init # add Bascik to an existing project
npx @bascik/language-server --check # the per-file checks on their own (bascik --check already runs them)bascik --checkbascik --checkbascik --checkNew project: . It and both write with and recommend the Bascik extension in , merging into files the folder already has. Third-party linters such as Webhint are opt-in: neither command installs them or creates or modifies their configs. A project set up any other way (a migration, or files copied in with ) needs that VS Code setting added by hand, or VS Code joins a page's blocks into one file and reports false errors such as "A module cannot have multiple default exports". The setting turns off only VS Code's own check of inline scripts, not Bascik's checks. Production builds need a site URL for and : (or , or ). Full CLI and error output: .
npm create bascik@rc my-site -ybascik init.vscode/settings.json"html.validate.scripts": false.vscode/extensions.jsonadd-example.mjs<script>sitemap.xmlrobots.txtBASCIK_SITE_URL=https://example.com bascik --build--site-url.envread-doc.mjs /clish
bascik # dev server at http://localhost:8080 with live reload and watch
bascik --build # production build to dist/ (HTML, CSS, JS, and identifier minification on)
bascik --build --only "blog/**" # rebuild matching pages without cleaning dist/
bascik --server # serve a built dist/ (needed for server/stream scripts and API routes)
bascik --check # project checks, plus the per-file checks when @bascik/language-server is installed
bascik --check --fix # also rewrite fixable findings (needs @bascik/language-server)
bascik add <package> # copy components from an installed npm package into src/components/
bascik init # add Bascik to an existing project
npx @bascik/language-server --check # the per-file checks on their own (bascik --check already runs them)bascik --checkbascik --checkbascik --check新项目:运行 。它和 都会写入 ,其中包含 ,并在 中推荐 Bascik extension,同时与文件中已有的设置合并。Webhint 等第三方 linter 属于可选项:这两个命令既不会安装它们,也不会创建或修改其配置。以其他方式设置的项目(例如迁移项目,或通过 复制文件的项目)需要手动添加该 VS Code setting,否则 VS Code 会将一个页面的多个 代码块合并为一个文件,并报告类似“A module cannot have multiple default exports”的虚假错误。该 setting 只会关闭 VS Code 自己对内联 script 的检查,不会关闭 Bascik 的检查。生产构建需要 site URL 来生成 和 :使用 (或 、)。完整 CLI 和错误输出参见 。
npm create bascik@rc my-site -ybascik init.vscode/settings.json"html.validate.scripts": false.vscode/extensions.jsonadd-example.mjs<script>sitemap.xmlrobots.txtBASCIK_SITE_URL=https://example.com bascik --build--site-url.envread-doc.mjs /cliVerify every change
验证每次修改
Do not stop at "the file looks right". Run these from the project root:
- runs
node <skill-dir>/scripts/verify.mjs(project and per-file checks) and, for component folders outside the project, the linter, then summarizes each step. Addbascik --checkto also run a production build.--build - reports oversized pages and components, inline sections that should be components, repeated blocks and heading groups, the same fact typed into several files, props every page passes with the same value, tiny single-use components, props passed through layers, JavaScript where TypeScript is expected, a hand-written HTML escaper or code that strips
node <skill-dir>/scripts/audit-components.mjs,<and>from a value (build the markup with&instead), ahtmlmodule that only one component or page uses (move it beside that user), and a component build script that should besrc/lib/(or a build-once script that reads the page). It also warns about semantic HTML: a clickabledata-bascik-build-onceor<div>, a component root that is a<span>where<div>,<nav>,<header>,<footer>,<form>, or<article>fits, a skipped heading level in a page's output, an<section>with no<img>, a form control with no label, and a page with noalt. Each finding has<main>and what to do. Passfile:lineonly when the person asked for JavaScript.--allow-js - compiles a snippet with the project's real components and config and prints the unminified output, so you can confirm scoped names, slot placement, and script rewrites.
node <skill-dir>/scripts/preview.mjs '<my-card data-bascik-prop-title="Hi" />' --count 2 - Read the relevant file in after a build. A hyphenated tag still present in
dist/means no component matched it.dist/
A page is not done until passes and exits 0. Fix each warning, or tell the person which one you kept and why (for example, a long legal page that is all prose). "The content differs" is not a reason to keep a repeated block: different text is what props and slots are for. Neither is "the fields belong to their form" when two forms repeat them.
verify.mjsaudit-components.mjs<skill-dir>.agents/skills/bascik不要停在“文件看起来没问题”这一步。从项目根目录运行以下命令:
- 会运行
node <skill-dir>/scripts/verify.mjs(项目检查和单文件检查),并对项目外的组件文件夹运行 linter,然后汇总每个步骤。添加bascik --check还会运行生产构建。--build - 会报告过大的页面和组件、应提取为组件的内联区块、重复区块和标题组、多个文件中重复输入的同一事实、每个页面都传入相同值的 props、微型单用途组件、跨层传递的 props、预期使用 TypeScript 却使用 JavaScript 的情况、手写 HTML escaper 或会从值中移除
node <skill-dir>/scripts/audit-components.mjs、<和>的代码(应使用&构造 markup)、仅由一个组件或页面使用的html模块(应移到该使用者旁),以及应使用src/lib/的组件构建 script(或读取页面的 build-once script)。它还会警告语义化 HTML 问题:可点击的data-bascik-build-once或<div>、本应使用<span>、<nav>、<header>、<footer>、<form>或<article>却使用<section>的组件根元素、页面输出中跳过的标题级别、缺少<div>的alt、没有 label 的表单控件,以及缺少<img>的页面。每项发现都会提供<main>和处理建议。只有在用户要求 JavaScript 时才传入file:line。--allow-js - 会使用项目真实的组件和配置编译一个代码片段,并打印未压缩输出,从而确认 scoped 名称、slot 位置和 script 重写结果。
node <skill-dir>/scripts/preview.mjs '<my-card data-bascik-prop-title="Hi" />' --count 2 - 构建后读取 中的相关文件。如果带连字符的标签仍然出现在
dist/中,说明没有组件与它匹配。dist/
只有当 通过且 以状态码 0 退出时,页面才算完成。修复每项警告,或者告诉用户你保留了哪项警告及其原因(例如全部为正文的长法律页面)。“内容不同”不能成为保留重复区块的理由:不同文本正是 props 和 slots 的用途。如果两个重复表单包含相同字段,“这些字段属于它们的表单”也不能成为保留重复区块的理由。
verify.mjsaudit-components.mjs<skill-dir>.agents/skills/bascikEditor linters read source; Bascik writes dist/
dist/Editor linter 读取源码;Bascik 写入 dist/
dist/webhint, axe, html-validate, HTMLHint, and VS Code's HTML checker read . Bascik overrules some of what they report, because the answer is only in the built page:
src/- Composed at build time: a missing charset or viewport (a head component adds them), an
<meta>link "should be specified in theapple-touch-icon" (a head component is a fragment with no<head>), a missing<head>(a build script writes it), an<title>with no<img>oraltand an empty heading whose value comes from asrcordata-bascik-attr-*prop.data-bascik-prop-* - Bascik syntax: self-closed component tags, component files with no doctype, and several blocks in one file (
<script>)."html.validate.scripts": false
Rules:
- Never "fix" one of these by adding the tag to a source page. Open the built page in first. If the tag is there, the warning is false and a second copy would ship twice; if it is missing there too, fix the head component or build script.
dist/ - Everything else is real: a with no
<button>,typewith no<html>, a literallangwith no<img>. The optional documentedaltturns.hintrcoff in the editor, so a literal missingimage-altshows only inaltand the built-site check: run them. The documentedaudit-components.mjsmakessrc/.htmlvalidate.json<img>optional, so a literalsrcwith no<img>shows only when html-validate checkssrc; never turndist/off for all ofelement-required-attributes, which also hides a missingsrc/.lang - Do not add third-party linter configs or dependencies by default. If the person uses Webhint or another linter, read and adapt its copyable configs to the project's folders. Preserve existing settings. Keep Webhint configs as plain JSON, because its extension's quick fixes use
/testing/linting#editor-linters-read-source. Keep the built-site config independent of the source config so source exceptions do not leak intoJSON.parse. Other linters get adist/config; HTMLHint's must list its default rules too, or unnamed checks are disabled.src/ - The checks that decide run on built output: for Bascik syntax and WHATWG parsing, then
bascik --check. If the person opts into Webhint, copy the documentedbascik --buildfirst, then run.hintrc.dist.json(files, not the folder; usenpx hint -c .hintrc.dist.json $(find dist -name '*.html')if it is notdirectory.out). Lighthouse ondistis another built-site audit. Webhint does not check local links: runbascik --server.check-links.mjs - cSpell on a brand or product name is real: add the name to the project's
Unknown wordcspell.json, not to a user setting."words"
Every warning, its setting, and the config files: .
read-doc.mjs /testing/linting#editor-linters-read-sourcewebhint、axe、html-validate、HTMLHint 和 VS Code HTML checker 读取 。Bascik 会推翻其中一部分报告,因为答案只存在于构建后的页面中:
src/- 在构建时组合: 缺少 charset 或 viewport (head component 会添加它们)、apple-touch-icon link 被提示“should be specified in the
<meta>”(head component 是没有<head>的 fragment)、缺少<head>(由 build script 写入)、<title>缺少<img>或alt,以及空 heading 的值来自src或data-bascik-attr-*prop。data-bascik-prop-* - Bascik 语法: 自闭合组件标签、没有 doctype 的组件文件,以及一个文件中的多个 代码块(
<script>)。"html.validate.scripts": false
规则:
- 绝不要通过向源页面添加标签来“修复”这些问题。 应先打开 中的构建页面。如果标签在那里,则该警告是误报,再添加一份会导致线上页面出现重复内容;如果构建页面中也缺少它,则应修复 head component 或 build script。
dist/ - 其他问题都是真实问题: 没有 的
type、没有<button>的lang、缺少<html>的字面量alt。可选的文档化<img>会关闭编辑器的.hintrc规则,因此字面量中缺少image-alt只会出现在alt和构建站点检查中:应运行这些检查。文档化的audit-components.mjs会让src/.htmlvalidate.json的<img>变成可选,因此字面量中缺少src只会出现在针对src的 html-validate 检查中;绝不要为所有dist/关闭src/,否则也会隐藏缺少element-required-attributes的问题。lang - 默认不要添加第三方 linter 配置或依赖。 如果用户使用 Webhint 或其他 linter,请阅读 并调整其中可复制的配置以适配项目文件夹。保留已有设置。Webhint 配置应保持为普通 JSON,因为其 extension 的快速修复使用
/testing/linting#editor-linters-read-source。构建站点配置应独立于源码配置,避免源码例外泄漏到JSON.parse。其他 linter 使用dist/配置;HTMLLint 的配置还必须列出其默认规则,否则未命名的检查会被禁用。src/ - 决定性检查应针对构建输出运行: 先运行 检查 Bascik 语法和 WHATWG 解析,再运行
bascik --check。如果用户选择使用 Webhint,请先复制文档化的bascik --build,然后运行.hintrc.dist.json(使用文件而不是文件夹;如果不是npx hint -c .hintrc.dist.json $(find dist -name '*.html'),则使用dist)。在directory.out上运行 Lighthouse 是另一种构建站点审计方式。Webhint 不会检查本地链接:请运行bascik --server。check-links.mjs - cSpell 对品牌或产品名称报告 是真实问题: 将该名称添加到项目的
Unknown wordcspell.json中,而不是添加到用户设置中。"words"
每项警告、对应设置和配置文件参见 。
read-doc.mjs /testing/linting#editor-linters-read-sourceBundled scripts
随附 scripts
All scripts are dependency-free Node.js (24.21+) and run from the project root. Each prints .
--help| Script | Purpose |
|---|---|
| |
| Page and component structure (too big, inline sections, repeats, tiny wrappers, prop drilling), semantic HTML (clickable divs, wrapper roots, heading order, alt, labels, |
| Compile a snippet, file, or existing page in a temporary build and print the result |
| Inventory components with their props, slots, companion files, and |
| Create a component folder that follows the naming and ordering rules |
| Search the live docs at bascik.dev for a topic |
| Print the current text of a docs page, such as |
| Copy a tested example component or part of the starter site from bascik.dev into the project ( |
| Find broken internal links, missing assets, and dead |
Run before creating a component so you reuse what exists instead of duplicating it.
list-components.mjs所有 script 都是无依赖的 Node.js(24.21+),并从项目根目录运行。每个 script 都支持 。
--help| Script | 用途 |
|---|---|
| 运行 |
| 检查页面和组件结构(过大、内联区块、重复、微型 wrapper、prop drilling)、语义化 HTML(可点击 div、wrapper 根元素、标题顺序、alt、label、 |
| 在临时构建中编译代码片段、文件或现有页面,并打印结果 |
| 盘点组件及其 props、slots、配套文件和 |
| 创建遵循命名和排序规则的组件文件夹 |
| 在 bascik.dev 的在线文档中搜索主题 |
| 打印当前文档页面的文本,例如 |
| 将 bascik.dev 中经过测试的示例组件或 starter site 的部分内容复制到项目中( |
| 在构建后的 |
创建组件前先运行 ,以复用已有组件而不是创建重复组件。
list-components.mjsLook it up in the docs
在文档中查找信息
The docs at https://bascik.dev are the reference; this skill only holds the rules. Read the page for any task below before writing code, instead of guessing:
sh
node <skill-dir>/scripts/read-doc.mjs /scripts/dynamic-routes
node <skill-dir>/scripts/search-docs.mjs "dynamic routes trailing slash"| How do I... | Read |
|---|---|
| Write components, slots, props, attributes | |
| Pick semantic elements, landmarks, headings, labels | |
Pass shared | |
| Use a library (petite-vue, Alpine.js, HTMX, Tailwind) | |
| Use a third-party web component | |
| Share components between projects | |
| Find answers to edge cases, fix a known problem | |
| Use the CLI and the dev server | |
The full page index is at https://bascik.dev/llms.txt.
https://bascik.dev 上的文档是权威参考;本 skill 只保存规则。完成以下任务时,应在编写代码前阅读对应页面,而不要猜测:
sh
node <skill-dir>/scripts/read-doc.mjs /scripts/dynamic-routes
node <skill-dir>/scripts/search-docs.mjs "dynamic routes trailing slash"| 如何完成…… | 阅读 |
|---|---|
| 编写组件、slots、props、attributes | |
| 选择语义化元素、landmarks、headings、labels | |
传递共享的 | |
| 使用库(petite-vue、Alpine.js、HTMX、Tailwind) | |
| 使用第三方 web component | |
| 在项目之间共享组件 | |
| 查找边缘情况的答案、修复已知问题 | |
| 使用 CLI 和 dev server | |
完整页面索引位于 https://bascik.dev/llms.txt。
Start from an example
从示例开始
https://bascik.dev/example-components has tested components (tabs, dialog, popover menu, copy button, filter list, contact form, theme toggle). also offers , a complete site (layout components, SEO helper, Markdown blog, feed, , contact page) whose README is at https://github.com/bascikdev/bascik/tree/main/examples/starter-site. Copy instead of writing from scratch, then adapt:
add-example.mjsstarter-sitellms.txtsh
node <skill-dir>/scripts/add-example.mjs --list
node <skill-dir>/scripts/add-example.mjs tab-group
node <skill-dir>/scripts/add-example.mjs starter-site/src/lib/seo.tsThe script downloads from bascik.dev, maps files to the project's configured folders, also copies example components a file uses, and writes nothing if any file would overwrite a different one. It prints and instead of copying them.
bascik.config.tspackage.jsonhttps://bascik.dev/example-components 提供了经过测试的组件(tabs、dialog、popover menu、copy button、filter list、contact form、theme toggle)。 还提供 ,这是一个完整站点(布局组件、SEO helper、Markdown blog、feed、、contact page),其 README 位于 https://github.com/bascikdev/bascik/tree/main/examples/starter-site。请复制而不是从零编写,然后进行适配:
add-example.mjsstarter-sitellms.txtsh
node <skill-dir>/scripts/add-example.mjs --list
node <skill-dir>/scripts/add-example.mjs tab-group
node <skill-dir>/scripts/add-example.mjs starter-site/src/lib/seo.ts该 script 会从 bascik.dev 下载文件,将它们映射到项目配置的文件夹,还会复制文件所使用的示例组件;如果任何文件会覆盖内容不同的已有文件,则不会写入任何内容。它会打印 和 ,而不是复制它们。
bascik.config.tspackage.jsonBuild a new site
构建新站点
- , or read the existing project first with
npm create bascik@rc my-site -y. Addlist-components.mjstoBASCIK_SITE_URL=https://example.com..env - Plan the pages and URLs (one purpose and one each), then the components each page is made of: the shared layout (head, header, footer), one component per section with a job, and one per repeated block. Plan repeated content (a collection in
<h1>) and anything that needs a server (API routes, per-request markup). Ask when the plan is unclear.content/ - Copy the foundation: , or only the parts you need. Then replace the example name, navigation (
add-example.mjs starter-site), colors (tokens insrc/components/site-header/links.ts), and every page'ssrc/pages/css/styles.css.seo({ title, description }) - Add components (or
new-component.mjs --script inline), then pages as lists of their tags, and interactive examples. Load the companion skill for each area.--script ts - Before launch: , then
npx bascik --build,verify.mjs,audit-components.mjs, thecheck-links.mjsaudit, and thebascik-seotoken check. The starter site README's "Build and Check It" section has the manual checklist.bascik-components
- 运行 ,或者先阅读现有项目并运行
npm create bascik@rc my-site -y。将list-components.mjs添加到BASCIK_SITE_URL=https://example.com。.env - 规划页面和 URL(每个页面只有一个用途和一个 ),然后规划组成每个页面的组件:共享布局(head、header、footer)、每个区块对应一个具有明确职责的组件,以及每个重复区块对应一个组件。规划重复内容(
<h1>中的集合)和所有需要 server 的内容(API routes、单请求 markup)。如果计划不明确,应向用户询问。content/ - 复制基础结构:,或只复制所需部分。然后替换示例名称、导航(
add-example.mjs starter-site)、颜色(src/components/site-header/links.ts中的 tokens),以及每个页面的src/pages/css/styles.css。seo({ title, description }) - 添加组件(或
new-component.mjs --script inline),然后将页面编写为标签列表,并添加交互示例。为每个领域加载配套 skill。--script ts - 启动前:运行 ,然后运行
npx bascik --build、verify.mjs、audit-components.mjs、check-links.mjs审计和bascik-seotoken 检查。starter site README 中的“Build and Check It”部分列出了手动检查清单。bascik-components
Companion skills
配套 Skills
| Skill | Load it when |
|---|---|
| Deciding what becomes a component, writing component CSS or TypeScript, interactivity, theming, scoped names |
| Responsive WebP, native srcset and sizes, stable gallery geometry, and correct selected variants before first paint |
| Deciding whether an HTML, CSS, or JavaScript feature works in browsers and inside a component |
| Using |
| Titles, descriptions, canonical URLs, social cards, JSON-LD, sitemap, |
| Creating or editing |
| Writing tests, debugging, validating output, or tuning Lighthouse scores |
| Moving a site from React, Next.js, Vue, Svelte, Astro, Eleventy, Hugo, or WordPress |
| Opt-in: having coding agents refactor a live site to production parity and 100 in all five Lighthouse categories |
New projects do not include . Install it with .
bascik-refactornpx skills add bascikdev/bascik --skill bascik-refactorIf the companions or this skill's folder are missing, the skill was installed as a single file. Reinstall the full set:
scripts/sh
npx skills add bascikdev/bascik| Skill | 何时加载 |
|---|---|
| 决定哪些内容应成为组件、编写组件 CSS 或 TypeScript、交互、主题、scoped 名称 |
| 响应式 WebP、原生 srcset 和 sizes、稳定的图库几何结构,以及首次绘制前选择正确变体 |
| 判断 HTML、CSS 或 JavaScript 功能是否可以在浏览器和组件内部正常工作 |
| 使用 |
| Titles、descriptions、canonical URLs、social cards、JSON-LD、sitemap、 |
| 创建或编辑 |
| 编写测试、调试、验证输出,或调整 Lighthouse 分数 |
| 从 React、Next.js、Vue、Svelte、Astro、Eleventy、Hugo 或 WordPress 迁移站点 |
| 可选:让 coding agent 将线上站点重构到功能与生产环境一致,并使五项 Lighthouse 指标全部达到 100 分 |
新项目不包含 。使用 安装。
bascik-refactornpx skills add bascikdev/bascik --skill bascik-refactor如果缺少配套 skills 或本 skill 的 文件夹,说明该 skill 是以单个文件形式安装的。请重新安装完整集合:
scripts/sh
npx skills add bascikdev/bascikor, without npx skills:
or, without npx skills:
mkdir -p .agents/skills && curl -fsSL https://bascik.dev/assets/skills.tar.gz | tar -xz -C .agents/skills
undefinedmkdir -p .agents/skills && curl -fsSL https://bascik.dev/assets/skills.tar.gz | tar -xz -C .agents/skills
undefined