Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

[React] Support static CRA assets #61

Closed
ittaibaratz opened this issue Mar 7, 2019 · 9 comments
Closed

[React] Support static CRA assets #61

ittaibaratz opened this issue Mar 7, 2019 · 9 comments

Comments

@ittaibaratz
Copy link
Collaborator

ittaibaratz commented Mar 7, 2019

The Create React App used by this archetype will create JS, CSS and static assets under the build folder:

image

However, aem-clientlib-generator used by this library will only copy the JS and CSS files.
As a result, when static resources are used by the app (Fonts, background images, etc) - They will be broken in AEM.

@ittaibaratz
Copy link
Collaborator Author

I managed to get the static assets over to AEM by tweaking clientlib.config.js:

...resources: [ "build/static/media/*.*" ]

The problem is that in the CSS files, the URL of the assets is something like:
http://localhost:4502/static/media/AvenirLTStd-Book.ecb0c2ae.otf

however in AEM we require that the URL get rewritten to something like
http://localhost:4502/etc.clientlibs/mysamplespa/clientlibs/mysamplespa-react/resources/AvenirLTStd-Book.ecb0c2ae.otf

@ittaibaratz
Copy link
Collaborator Author

Raised wcm-io-frontend/aem-clientlib-generator#14 which will be required in order to solve this.

@godanny86
Copy link
Collaborator

@ittaibaratz another alternative would be to add an additional webpack module to build process to rewrite the compiled CSS before using clientlib-generator to move it into a client-library...

@ittaibaratz
Copy link
Collaborator Author

ittaibaratz commented Mar 7, 2019

@ittaibaratz another alternative would be to add an additional webpack module to build process to rewrite the compiled CSS before using clientlib-generator to move it into a client-library...

I think it's cleaner to rewrite only in the AEM folder, this way the built scripts inside the react project's build folder will still work independently.

I have created a PR in aem-clientlib-generator which will enable this. If they don't accept, we can do the rewriting after the clientlib was generated inside the AEM folder - This is very easy to do with replace-in-file

@ittaibaratz ittaibaratz changed the title Support for static assets in React [React] Support static CSS assets Mar 9, 2019
@lydiapuric
Copy link
Contributor

@ittaibaratz Thanks for taking care of this issue and driving the discussion.

@ittaibaratz
Copy link
Collaborator Author

I have closed the PR - Will look for a cleaner alternative which will support both CSS and JS.

@ittaibaratz
Copy link
Collaborator Author

ittaibaratz commented Mar 15, 2019

I have done some research and here are the possible options to support CRA static assets within AEM:

  1. Rewrite the URLs in the CSS and JS files after they have been compiled. This works but its not very clean.

  2. Use an existing react-scripts fork that allows tweaking the CRA webpack config. For example react-app-rewired or react-scripts-rewired

  3. Create our own fork of react-scripts and tweak the webpack config in there. This is the recommended approach - See Alternatives to ejecting

@ittaibaratz ittaibaratz changed the title [React] Support static CSS assets [React] Support static CRA assets Mar 15, 2019
@ittaibaratz
Copy link
Collaborator Author

ittaibaratz commented Mar 21, 2019

For my own app, I've decided to use react-scripts-rewired which is the simplest solution to allow webpack override. Here are the steps I've taken. These make sure all assets work in AEM when referenced in both CSS and JS: (Note PROJECT should be replaced with actual project name)

  1. Install react-scripts-rewired:

npm install --save-dev react-scripts-rewired

  1. Created webpack.config.extend.js at the react root folder with the following content:
    (This is hard coded, so ideally should be more robust - But works well with CRA 2.0 webpack config)
module.exports = function override(config, env) {
  config.module.rules[2].oneOf[0].options.name = "etc.clientlibs/<PROJECT>/clientlibs/<PROJECT>-react/resources/[name].[ext]";
  config.module.rules[2].oneOf[7].options.name = "etc.clientlibs/<PROJECT>/clientlibs/<PROJECT>-react/resources/[name].[ext]";
  return config;
}
  1. Also created webpackDevServer.config.extend.js :
module.exports = function override(config, env) {
  return config;
};
  1. Changed clientlib.config.js as follows:
        assets: {
            js: [
                "build/static/**/*.js"
            ],
            css: [
                "build/static/**/*.css"
            ],
            resources: [
              "build/etc.clientlibs/<PROJECT>/clientlibs/<PROJECT>-react/resources/*.*"
            ]
        }
  1. Add the following line to the .env file:
SKIP_PREFLIGHT_CHECK=true

@cqsapient
Copy link

hi @ittaibaratz
I am facing the same issue and trying to implement your solution, however when I try to run npm install after installing react-scripts-rewired; I get the following error -

npm ERR! code ETARGET
npm ERR! notarget No matching version found for react-scripts-rewired@^3.0.1--latest1
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget
npm ERR! notarget It was specified as a dependency of 'react-app'
npm ERR! notarget

would you know what might be the issue here, did you also face the same issue?

Will appreciate your reply.

Thanks

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants