通常,你不会直接与 Svelte 编译器交互,而是使用打包器插件将其集成到你的构建系统中。 Svelte 团队最推荐和投资的打包器插件是 vite-plugin-svelte。 SvelteKit 框架提供了利用 vite-plugin-svelte
和 用于打包 Svelte 组件库的工具 构建应用的设置。 Svelte Society 维护着一个 其他打包器插件 列表,用于附加工具,例如 Rollup 和 Webpack。
英Typically, you won't interact with the Svelte compiler directly, but will instead integrate it into your build system using a bundler plugin. The bundler plugin that the Svelte team most recommends and invests in is vite-plugin-svelte. The SvelteKit framework provides a setup leveraging vite-plugin-svelte
to build applications as well as a tool for packaging Svelte component libraries. Svelte Society maintains a list of other bundler plugins for additional tools like Rollup and Webpack.
尽管如此,了解如何使用编译器还是很有用的,因为打包器插件通常会向你公开编译器选项。
英Nonetheless, it's useful to understand how to use the compiler, since bundler plugins generally expose compiler options to you.
compilepermalink
导出片段: svelte/compiler#compile
这就是奇迹发生的地方。 svelte.compile
获取你的组件源代码,并将其转换为导出类的 JavaScript 模块。
英This is where the magic happens. svelte.compile
takes your component source code, and turns it into a JavaScript module that exports a class.
ts
import {compile } from 'svelte/compiler';constresult =compile (source , {// options});
有关所有可用选项,请参阅 CompileOptions。
英Refer to CompileOptions for all the available options.
返回的 result
对象包含组件的代码以及有用的元数据。
英The returned result
object contains the code for your component, along with useful bits of metadata.
ts
const {js ,css ,ast ,warnings ,vars ,stats } =compile (source );
有关编译结果的完整说明,请参阅 CompileResult。
英Refer to CompileResult for a full description of the compile result.
parsepermalink
导出片段: svelte/compiler#parse
parse
函数解析组件,仅返回其抽象语法树。 与使用 generate: false
选项进行编译不同,除了解析组件之外,这不会对组件执行任何验证或其他分析。 请注意,返回的 AST 不被视为公共 API,因此任何时间点都可能发生重大更改。
英The parse
function parses a component, returning only its abstract syntax tree. Unlike compiling with the generate: false
option, this will not perform any validation or other analysis of the component beyond parsing it. Note that the returned AST is not considered public API, so breaking changes could occur at any point in time.
ts
import {parse } from 'svelte/compiler';constast =parse (source , {filename : 'App.svelte' });
preprocesspermalink
导出片段: svelte/compiler#preprocess
许多 官方和社区维护的预处理插件 可让你将 Svelte 与 TypeScript、PostCSS、SCSS 和 Less 等工具一起使用。
英A number of official and community-maintained preprocessing plugins are available to allow you to use Svelte with tools like TypeScript, PostCSS, SCSS, and Less.
你可以使用 svelte.preprocess
API 编写自己的预处理器。
英You can write your own preprocessor using the svelte.preprocess
API.
preprocess
函数为任意转换组件源代码提供了方便的钩子。 例如,它可用于将 <style lang="sass">
块转换为普通 CSS。
英The preprocess
function provides convenient hooks for arbitrarily transforming component source code. For example, it can be used to convert a <style lang="sass">
block into vanilla CSS.
第一个参数是组件源代码。 第二个是预处理器数组(或者单个预处理器,如果只有一个),其中预处理器是一个对象,其中包含必需的 name
以及 markup
、script
和 style
函数,其中每个函数都是可选的。
英The first argument is the component source code. The second is an array of preprocessors (or a single preprocessor, if you only have one), where a preprocessor is an object with a name
which is required, and markup
, script
and style
functions, each of which is optional.
markup
函数接收整个组件源文本,以及组件的 filename
(如果在第三个参数中指定)。
英The markup
function receives the entire component source text, along with the component's filename
if it was specified in the third argument.
script
和 style
函数分别接收 <script>
和 <style>
元素的内容 (content
) 以及整个组件源文本 (markup
)。 除了 filename
之外,它们还获取元素属性的对象。
英The script
and style
functions receive the contents of <script>
and <style>
elements respectively (content
) as well as the entire component source text (markup
). In addition to filename
, they get an object of the element's attributes.
每个 markup
、script
或 style
函数必须返回一个带有 code
属性的对象(或解析为对象的 Promise),表示转换后的源代码。 他们可以选择返回一个 dependencies
数组(表示要监视更改的文件)和一个 map
对象(将转换映射回原始代码的源映射)。 script
和 style
预处理器可以选择返回表示脚本/样式标记上更新的属性的属性记录。
英Each markup
, script
or style
function must return an object (or a Promise that resolves to an object) with a code
property, representing the transformed source code. Optionally they can return an array of dependencies
which represents files to watch for changes, and a map
object which is a sourcemap mapping back the transformation to the original code. script
and style
preprocessors can optionally return a record of attributes which represent the updated attributes on the script/style tag.
预处理器函数应尽可能返回
map
对象,否则调试会变得更加困难,因为堆栈跟踪无法正确链接到原始代码。
ts
import {preprocess } from 'svelte/compiler';importMagicString from 'magic-string';const {code } = awaitpreprocess (source ,{markup : ({content ,filename }) => {constpos =content .indexOf ('foo');if (pos < 0) {return {code :content };}consts = newMagicString (content , {filename });s .overwrite (pos ,pos + 3, 'bar', {storeName : true });return {code :s .toString (),map :s .generateMap ()};}},{filename : 'App.svelte'});
如果返回 dependencies
数组,它将包含在结果对象中。 vite-plugin-svelte 和 rollup-plugin-svelte 之类的包使用它来监视其他文件的更改,例如,如果你的 <style>
标签具有 @import
,则可以使用此功能。
英If a dependencies
array is returned, it will be included in the result object. This is used by packages like vite-plugin-svelte and rollup-plugin-svelte to watch additional files for changes, in the case where your <style>
tag has an @import
(for example).
ts
import {preprocess } from 'svelte/compiler';importMagicString from 'magic-string';importsass from 'sass';import {dirname } from 'path';const {code } = awaitpreprocess (source ,{name : 'my-fancy-preprocessor',markup : ({content ,filename }) => {// Return code as is when no foo string presentconstpos =content .indexOf ('foo');if (pos < 0) {return;}// Replace foo with bar using MagicString which provides// a source map along with the changed codeconsts = newMagicString (content , {filename });Property 'css' does not exist on type 'unknown'.s .overwrite ( pos ,pos + 3, 'bar', {storeName : true });
Property 'stats' does not exist on type 'unknown'.2339
2339Property 'css' does not exist on type 'unknown'.
Property 'stats' does not exist on type 'unknown'.return {code :s .toString (),map :s .generateMap ({hires : true,file :filename })};Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'.2345Argument of type 'string | undefined' is not assignable to parameter of type 'string'. Type 'undefined' is not assignable to type 'string'.},style : async ({content ,attributes ,filename }) => {// only process <style lang="sass">if (attributes .lang !== 'sass') return;const {css ,stats } = await newPromise ((resolve ,reject ) =>sass .render ({file :filename ,data :content ,includePaths : [dirname (filename )]},(err ,result ) => {if (err )reject (err );elseresolve (result );}));// remove lang attribute from style tagdeleteattributes .lang ;return {code :css .toString (),dependencies :stats .includedFiles ,attributes };}},{filename : 'App.svelte'});
多个预处理器可以一起使用。 第一个的输出成为第二个的输入。 在一个预处理器中,markup
首先运行,然后是 script
和 style
。
英Multiple preprocessors can be used together. The output of the first becomes the input to the second. Within one preprocessor, markup
runs first, then script
and style
.
在 Svelte 3 中,所有
markup
函数首先运行,然后是所有script
,最后是所有style
预处理器。 这个顺序在 Svelte 4 中发生了变化。
ts
import {preprocess } from 'svelte/compiler';const {code } = awaitpreprocess (source , [{name : 'first preprocessor',markup : () => {console .log ('this runs first');},script : () => {console .log ('this runs second');},style : () => {console .log ('this runs third');}},{name : 'second preprocessor',markup : () => {console .log ('this runs fourth');},script : () => {console .log ('this runs fifth');},style : () => {console .log ('this runs sixth');}}], {filename : 'App.svelte'});
ts
import {preprocess } from 'svelte/compiler';const {code } = awaitpreprocess (source ,[{name : 'first preprocessor',markup : () => {console .log ('this runs first');},script : () => {console .log ('this runs second');},style : () => {console .log ('this runs third');},},{name : 'second preprocessor',markup : () => {console .log ('this runs fourth');},script : () => {console .log ('this runs fifth');},style : () => {console .log ('this runs sixth');},},],{filename : 'App.svelte',},);
walkpermalink
导出片段: svelte/compiler#walk
walk
函数提供了一种使用编译器自己的内置 estree-walker 实例来遍历解析器生成的抽象语法树的方法。
英The walk
function provides a way to walk the abstract syntax trees generated by the parser, using the compiler's own built-in instance of estree-walker.
walker 需要一个抽象语法树来行走,以及一个具有两个可选方法的对象: enter
和 leave
。 对于每个节点,都会调用 enter
(如果存在)。 然后,除非在 enter
期间调用 this.skip()
,否则将遍历每个子节点,然后在该节点上调用 leave
。
英The walker takes an abstract syntax tree to walk and an object with two optional methods: enter
and leave
. For each node, enter
is called (if present). Then, unless this.skip()
is called during enter
, each of the children are traversed, and then leave
is called on the node.
ts
import {walk } from 'svelte/compiler';walk (ast , {enter (node ,parent ,prop ,index ) {do_something (node );if (should_skip_children (node )) {this.skip ();}},leave (node ,parent ,prop ,index ) {do_something_else (node );}});
ts
import {walk } from 'svelte/compiler';walk (ast , {enter (node ,parent ,prop ,index ) {do_something (node );if (should_skip_children (node )) {this.skip ();}},leave (node ,parent ,prop ,index ) {do_something_else (node );},});
VERSIONpermalink
导出片段: svelte/compiler#VERSION
当前版本,在 package.json 中设置。
英The current version, as set in package.json.
ts
import {VERSION } from 'svelte/compiler';console .log (`running svelte version ${VERSION }`);
类型(Types)permalink
类型: svelte/compiler