liferay / liferay-frontend-projects

A monorepo containing assorted Frontend Infrastructure Team projects
Other
66 stars 67 forks source link

Budler converts custom scripts properly, but final JAR contains the original stuff #1131

Closed jan-tosovsky-cz closed 1 year ago

jan-tosovsky-cz commented 1 year ago

👀 Please check the troubleshooting guide before reporting anything. It contains important information on how to fix or diagnose errors.

Issue type (mark with x)

Version (mark with x)

Description

I am employing a management toolbar in my OSGi portlet. Its integration is almost identical to the site-navigation-admin-web module https://github.com/liferay/liferay-portal/tree/master/modules/apps/site-navigation/site-navigation-admin-web

I use Gradle with the workspace configured to use NPM manager: liferay.workspace.node.package.manager=npm

My package.json is very simple

{
  "dependencies": {
    "frontend-js-web": "*"
  },
  "name": "tms-projects-admin-web",
  "scripts": {
    "build": "liferay-npm-scripts build",
    "checkFormat": "liferay-npm-scripts check",
    "format": "liferay-npm-scripts fix"
  },
  "version": "1.0.0",
  "devDependencies": {
    "@liferay/npm-scripts": "^47.18.0"
  }
}

There is no custom npmscripts.config.js file in my project.

When deploy goal is run, all my scripts are properly converted to the syntax Liferay.Loader.define(...) and they are minified. But all this happens in the \build\node\packageRunBuild\resources folder. However, the final JAR contains the original resources folder without those JS modifications.

image

I was looking for the root cause, but I could only find addBuildFiles(zip) method in the bundler source. It is suspicious as it takes just the resources folder, but those processed are sideways:

function addBuildFiles(zip) {
    addFiles(
        project.buildDir.asNative,
        ['**/*', `!${project.jar.outputFilename}`],
        zip.folder('META-INF').folder('resources')
    );
}

But there could be some missing settings in my config.

Desired behavior: The final JAR contains processed files.

Current behavior: The final JAR contains original files, both package.json and manifest.json are missing.

Repro instructions (if applicable): I expect it would quite complex for you to prepare an identical environment.

Other information (environment, versions etc): Node v16.14.0, IntelliJ IDEA, Gradle 6.9.4

izaera commented 1 year ago

Mmm, that's not an error in the bundler, but in the Workspace, since the bundler doesn't package the JAR at all when used inside a workspace. However, this repo (and team behind it) doesn't maintain that tool so I'm going to close this.

I'm not sure what's the proper way to report Workspace bugs... :thinking: If you have a paid subscription you can use Liferay support services, for sure.

izaera commented 1 year ago

Mmm, I've noticed you are using liferay-npm-scripts but that's only for internal use of the liferay-portal project...

izaera commented 1 year ago

In short: the configuration you are reporting is not supported. You can only use the samples provided by the workspace or the JS Toolkit as explained in -> https://github.com/liferay/liferay-frontend-projects/tree/master/projects/js-toolkit/docs

For your case, since you need both Java and JavaScript support your best bet would be starting with a hybrid Java/JavaScript MVC portlet then build on top of that by tweaking the project.

jan-tosovsky-cz commented 1 year ago

I liked the code used in one LR module (site-navigation-admin-web) and tried to replicate it (I usually take LR code base as the recommended approach to do things). This is the reason for using the liferay-npm-scripts stuff.

jan-tosovsky-cz commented 1 year ago

After some digging I was able to produce JAR with all required stuff by tweaking the build.gradle config

jar {
    doFirst{
        copy {
            from layout.buildDirectory.dir("node/packageRunBuild")
            into layout.buildDirectory.dir("resources/main/META-INF")
        }
    }
}
izaera commented 1 year ago

If it works for you it's OK :+1:

However, keep in mind that liferay-npm-scripts is internal and subject to changes (even breaking ones) without any kind of support or warning, so, you are on your own.

Glad to see that you could make it work, anyway :-)

jan-tosovsky-cz commented 1 year ago

I understand this is rather a hack. And there are still issues.

It only works unless I import some LR module in my code:

import {openSimpleInputModal} from 'frontend-js-web';
Error: Unsatisfied dependency: tms-projects-admin-web$frontend-js-web found in module tms-projects-admin-web@1.0.0/js/ProjectManagementToolbarPropsTransformer

But this is another issue I'll have to investigate. Reusing the LR modal window is the main goal I want to achieve here so without it the entire idea would have to be abandoned.

izaera commented 1 year ago

Your build is missing this setting -> https://github.com/liferay/liferay-portal/blob/master/modules/npmscripts.config.js#L220 and you will need to fool liferay-npm-scripts to make it read it from somewhere (in here -> https://github.com/liferay/liferay-frontend-projects/blob/master/projects/npm-tools/packages/npm-scripts/src/utils/getMergedConfig.js#L172).

However that's even more hacky than using liferay-npm-scripts :sweat_smile:

jan-tosovsky-cz commented 1 year ago

Thanks a lot for this missing piece in my puzzle! I've already met some customizations done via the project-specific npmscripts.config.js. I've tried now this

module.exports = {
    build: {
        bundler: {
            config: {
                imports: {
                    'frontend-js-web': {
                        '/': '*',
                    }
                }
            }
        }
    }
}

and it works like a charm! You saved me a day. Thanks a lot for pointing me to the right direction.

jan-tosovsky-cz commented 1 year ago

Anyway, I'll try other channels to discuss what is the proper way for such customizations.

izaera commented 1 year ago

Glad it helped you :blush: