You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在独立Prettier API中集成第三方Java插件?

网页扩展集成Prettier Java插件问题

我正在开发一款工作用网页扩展,通过Prism和Prettier将文本转换为格式化代码块,主要支持TypeScript和Java。TypeScript插件是Prettier内置的,实现起来很顺利,但第三方Java插件的集成遇到了诸多问题,找不到独立Prettier环境下的实现说明。

目前遇到的几个关键错误:

  • 浏览器控制台报错:ConfigError: Couldn't resolve parser "java". Plugins must be explicitly added to the standalone bundle.
  • 导入Java插件时构建失败:Error: Can't walk dependency graph: Cannot find module 'prettier-plugin-java',试过require("prettier-plugin-java")和require("./node_modules/prettier-plugin-java")两种写法
  • 切换为esmify后构建成功,但控制台出现CSP相关错误:Error formatting code: EvalError: call to Function() blocked by CSP
  • 尝试过.prettierrc.json/.prettierrc.js配置文件,但因为使用Prettier API而非CLI,配置未生效

以下是当前测试阶段的代码(先在HTML中验证再移植到扩展):


codeblock.html

<html style="background-color: #fff">
<head>
    <link href="themes/prism.css" rel="stylesheet"/>
    <title>Code Block</title>
    <header></header>
    <script src="bundle.js"></script>
</head>
<body>
<header data-plugin-header="show-language"></header>
<pre><code class="language-java">
<!--  Purposefully formatted poorly to ensure Prettier is working  -->
      package com.example;

    public class Main {

        public static void main(String[] args) {
                        System.out.println("Hello World!");

                }
    }
</code></pre>
<script src="prism.js"></script>
</body>
</html>

format.js

const prettier = require("prettier");
const typescript = require("./node_modules/prettier/plugins/typescript");
const babel = require("./node_modules/prettier/plugins/babel");
const estree = require("./node_modules/prettier/plugins/estree");
const html = require("./node_modules/prettier/plugins/html");
const markdown = require("./node_modules/prettier/plugins/markdown");
const postcss = require("./node_modules/prettier/plugins/postcss");
const yaml = require("./node_modules/prettier/plugins/yaml");

/* Takes in code string and language and attempts to reformat using Prettier API */
async function formatCode(code, language) {
    try {
        let parser = language;

        return await prettier.format(code, {
            organizeImportsSkipDestructiveCodeActions: true,
            parser: parser,
            plugins: [typescript, babel, estree, html, markdown, postcss, yaml, require('prettier-plugin-java')],
            tabWidth: 2,
            useTabs: true,
            semi: true,
            singleQuote: false,
            trailingComma: "none",
            bracketSpacing: true,
            arrowParens: "always",
        });
    } catch (error) {
        console.error("Error formatting code:", error);
        return code;
    }
}

/* Grabs the code chunk from the HTML, parses the code (text) and language from it, and calls formatCode() */
setTimeout(async () => {
    for (const code of document.querySelectorAll("code")) {
        const language = code.className.replace("language-", "");
        if(language != null && language.trim() !== "") {
            code.parentElement.style.setProperty("--before-content", `'${language.toUpperCase()}'`);
            code.innerText = await formatCode(code.innerText, language);
        }
    }

    Prism.highlightAll();
}, 1000)

build.js

const browserify = require('browserify');
const fs = require('fs');

browserify(['format.js'])
    .transform('babelify', { presets: ['@babel/preset-env'] })
    .bundle((err, buf) => {
        if (err) {
            console.error(err);
        } else {
            fs.writeFileSync('bundle.js', buf);
        }
    });

替代build.js(尝试esmify)

const browserify = require('browserify');
const esmify = require('esmify');
const fs = require('fs');

browserify(['format.js', 'render.js'], {plugin: [[esmify, {nodeModules: true}]]})
    .require(require.resolve('java-parser'), {expose: 'java-parser'})
    .require(require.resolve('chevrotain'), {expose: 'chevrotain'})
    .require(require.resolve('chevrotain-allstar'), {expose: 'chevrotain-allstar'})
    .bundle((err, buf) => {
        if (err) {
            console.error(err);
        } else {
            fs.writeFileSync('bundle.js', buf);
        }
    });

package.json

{
  "name": "agility-code-chunks",
  "version": "1.0.0",
  "description": "web extension to format code chunks in agility",
  "main": "popup.js",
  "scripts": {
    "build": "node build.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "nop990",
  "license": "MIT",
  "devDependencies": {
    "@babel/preset-env": "^7.25.2",
    "babelify": "^10.0.0",
    "browserify": "^17.0.0",
    "google-java-format": "^1.3.2",
    "prettier": "^3.2.5",
    "prettier-plugin-java": "^2.6.4",
    "prettier-plugin-organize-imports": "^4.0.0"
  },
  "dependencies": {
    "java-parser": "^2.3.2"
  }
}

内容的提问来源于stack exchange,提问作者nop990

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:39:53