如何在NextJS项目中添加Web树保姆?

ohtdti5x  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(104)

我希望能够通过解析我的NextJS Web应用程序上键入的代码来生成AST。我看到我应该使用web-tree-sitter来实现这样的事情。
我成功地使用Docker生成了tree-sitter-JavaScript.wasm文件,将其移动到与Page.tsx文件相同的目录中(我想在那里调用解析函数),并像这样加载解析器:(如他们的npm包的网站上所述)。

locateFile(scriptName: string, scriptDirectory: string) {
       return scriptName;
     },
   });

然后像这样定义解析器和JavaScript语法,

const JavaScript = await Parser.Language.load('tree-sitter-javascript.wasm');
  parser.setLanguage(JavaScript);

我收到这个错误:

./node_modules/web-tree-sitter/tree-sitter.js:1:1044
Module not found: Can't resolve 'fs'

我还在npm包的网站上读到,添加了一个webpack配置,使编译器忽略浏览器中不存在的Node的fs。我尝试通过next.js.js添加它,如下所示:

const nextConfig = {
    // Other next.js config
  
    // webpack: (config, options) => {
    //   config.resolve.fallback = {
    //     fs: false,
    //   }
  
    //   return config
    // }
  }
  
  module.exports = nextConfig

但是,我仍然得到无法解决fs错误。
我应该做些什么不同的事情?

vi4fp9gy

vi4fp9gy1#

我设法让web-tree-sitter在我的项目上工作。以下是方法:
将Webpack配置添加到next.config.js文件:

module.exports = {
    webpack: (config, options) => {
    config.resolve.fallback = {
      fs: false,
    }

    return config
  },
}

tree-sitter.wasmtree-sitter-javascript.wasm文件添加到public/文件夹。
这应该与最新的NextJS一起工作。下面是一个应用程序路由器(page.tsx)的示例:

"use client"

import React from "react"
import Parser from "web-tree-sitter"

const exampleCode = `
const MyComp = () => {
  const [count, setCount] = React.useState(0)
  return (
    <div>
      <h1 className="text-4xl">Hello World</h1>
      <button onClick={() => setCount(count + 1)}>Click Me</button>
      <p>Count: {count}</p>
    </div>
  )
}
`

export default function TreeSitterTest() {
  const [isReady, setIsReady] = React.useState(false)
  const [code, setCode] = React.useState(exampleCode)
  const [AST, setAST] = React.useState<Parser.Tree | null>(null)

  const parserRef = React.useRef<Parser>()

  React.useEffect(() => {
    ;(async () => {
      await Parser.init({
        locateFile(scriptName: string, scriptDirectory: string) {
          return scriptName
        },
      })

      const parser = new Parser()
      const Lang = await Parser.Language.load("tree-sitter-javascript.wasm")

      setIsReady(true)

      parser.setLanguage(Lang)

      parserRef.current = parser
    })()
  }, [])

  React.useEffect(() => {
    if (!isReady) return
    if (!parserRef.current) return

    const tree = parserRef.current.parse(code)
    console.log("rootNode:", tree.rootNode)

    setAST(tree)
  }, [code, isReady])

  return (
    <div>
      <h1 className="p-2 text-4xl">Tree Sitter Test</h1>

      <div className="flex-cole flex h-96 gap-1 p-1">
        <textarea
          className="rounder-sm flex-1 overflow-auto whitespace-pre-wrap border border-gray-300 p-2"
          value={code}
          onChange={(e) => setCode(e.target.value)}
        />
        <div className="rounder-sm flex-1 overflow-auto whitespace-pre-wrap border border-gray-300 p-2">
          {AST?.rootNode.toString()}
        </div>
      </div>
    </div>
  )
}

我实现这个的项目是OSS,所以你可以直接在那里查看:

相关问题