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

Grails 3.3.8打包WAR时未包含React生成的bundle.js静态资源

Grails 3.3.8打包WAR时未包含React生成的bundle.js静态资源

我最近碰到一个头疼的问题:把React项目打包生成的bundle.js想整合到Grails的WAR包中,在IntelliJ IDEA里直接运行Grails项目时,页面能正常加载React应用,但用grails war命令打包后,部署到服务器就发现React应用没了——查了下WAR包,居然没包含bundle.js的内容!

我的环境与配置信息

  • Grails版本:3.3.8
  • JDK版本:1.8.0_432

gradle.properties内容:

grailsVersion=3.3.8
gormVersion=6.1.10.RELEASE
gradleWrapperVersion=3.5

build.gradle关键配置片段:

buildscript {
    repositories {
        mavenLocal()
        maven { url "https://repo.grails.org/grails/core" }
    }
    dependencies {
        classpath "org.grails:grails-gradle-plugin:$grailsVersion"
        classpath "org.grails.plugins:hibernate5:${gormVersion-"RELEASE"}"
        classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.14.8"
    }
}

version "0.1"
group "myapp"

apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"war"
apply plugin:"org.grails.grails-web"
apply plugin:"asset-pipeline"
apply plugin:"org.grails.grails-gsp"
apply plugin:"java"
apply plugin:"io.spring.dependency-management"

war.archiveName='myapp.war'

// 依赖配置省略...

assets {
    minifyJs = true
    minifyCss = true
}

jar {
    manifest {
        attributes 'Main-Class': 'myapp.Application'
    }
}

war {
    manifest {
        attributes 'Main-Class': 'myapp.Application'
    }
}

GSP页面中引用bundle.js的代码:

<div id="react-root"></div>
    <asset:javascript src="bundle.js"/>
</div>

我已经尝试过的方法(但都没生效)

  1. 参考了相关问题里提到的资产插件配置调整,没有解决
  2. 在Application.groovy和application.yml中配置排除bundle.js的压缩,无效:
    • Application.groovy配置:
      grails.assets = [
              minifyJs: false,
              minifyCss: true,
              minifyOptions: [
                      excludes: [
                              '**/jquery-2.2.0.min.js',
                              '**/bundle.js'
                      ]
              ]
      ]
      
    • application.yml配置:
      grails:
          assets:
              minifyJs: true
              minifyCss: true
              minifyOptions:
                  excludes:
                      - '**/jquery-2.2.0.min.js'
                      - '**/bundle.js'
      
  3. 在application.js中添加//= bundle.js,也没效果

针对这个问题的解决建议

1. 确保bundle.js在Asset Pipeline的扫描范围内

Grails的Asset Pipeline默认只扫描grails-app/assets/javascripts/目录,你要么把React生成的bundle.js复制到这个目录,要么在build.gradle里配置额外的资产源目录:

assets {
    sourceDirs = ['grails-app/assets', 'src/main/webapp/react-dist'] // 替换成你的React打包输出目录
    minifyJs = true
    minifyCss = true
}

2. 用正确的Asset Pipeline语法导入bundle.js

在grails-app/assets/javascripts/application.js中,用require语法导入bundle.js,确保它被纳入资产编译流程:

//= require bundle.js

这里要注意,//= bundle是用来定义打包组的,单个文件导入要用require。

3. 让React打包任务先于Grails资产编译执行

要确保React先打包生成最新的bundle.js,再让Grails处理资产。在build.gradle中添加任务依赖:

// 定义React打包任务
task npmBuild(type: Exec) {
    workingDir 'path/to/your/react-project' // 替换为你的React项目根目录
    if (System.getProperty('os.name').toLowerCase().contains('windows')) {
        commandLine 'cmd', '/c', 'npm', 'run', 'build' // Windows环境
    } else {
        commandLine 'npm', 'run', 'build' // 类Unix环境
    }
}

// 让Grails的资源处理任务依赖于React打包任务
processResources.dependsOn npmBuild
assets.dependsOn npmBuild

4. 验证资产编译结果

执行./gradlew asset-compile(或gradlew.bat asset-compile)命令,然后查看build/assets/javascripts目录下是否有bundle.js。如果这里能找到,说明资产编译正常,WAR打包时就会包含它。

5. 移除WAR包中不必要的Main-Class配置

Grails WAR包不需要Main-Class属性(这是给可执行JAR用的),可以删除war块里的manifest配置,避免潜在冲突:

// 移除这段配置
war {
    manifest {
        attributes 'Main-Class': 'myapp.Application'
    }
}

备注:内容来源于stack exchange,提问作者Amit Thakur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:08:07