Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support URL rewriting for static assets referenced in CSS files. #14

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

Comments

@ittaibaratz
Copy link

This is related to adobe/aem-spa-project-archetype#61

When using Create React App (And other frameworks using webpack), the static assets are automatically copied to the build folder and their URL is updated. For example, in my CSS file I have the following font family definition:

@font-face { font-family: AvenirBook; src: url("resources/AvenirLTStd-Book.otf") format("opentype"); }

When my app is compiled, the result CSS will have the following URL:
src:url(/static/media/AvenirLTStd-Book.ecb0c2ae.otf)

I can copy the static assets to the AEM clientlib however with the resources configuration, however the URL which appears in the CSS will no longer work, as AEM needs a URL such as
/etc.clientlibs/mysamplespa/clientlibs/mysamplespa-react/resources/AvenirLTStd-Book.ecb0c2ae.otf

My suggestion to resolve this is to add the ability to rewrite the CSS files through regex.
So to solve the problem above I want to be able to automatically replace "/static/media" with "/etc.clientlibs/mysamplespa/clientlibs/mysamplespa-react/resources" in the CSS files.

@ittaibaratz ittaibaratz changed the title Support URL writing for static assets Support URL rewriting for static assets referenced in CSS files. Mar 7, 2019
@stefanseifert
Copy link
Member

thanks for the contribution, we'll have a look at the PR

@ifahrentholz
Copy link
Member

ifahrentholz commented Mar 15, 2019

Hi @ittaibaratz,

the purpose of the aem-clientlib-generator is to copy files from your dist folder into the AEM (clientlib) context and create the *.txt files.

The aem-clientlib-generator should not be responsible for "compile" tasks like url rewriting.
Therefore you should use tools which are designed to do just that - like webpack.

I've investigated a little and the create-react-app uses under the hood webpack and the url-loader.
The url-loader accepts the argument publicPath which when it's set will do exactly what you are asking for.

You can adjust these settings when you run npm run eject in your CRA project.

I can imagine that you want to avoid ejecting your project. If that's so you can take a look at:

  1. https://facebook.github.io/create-react-app/docs/alternatives-to-ejecting
  2. Or consider using something like: https://github.com/timarney/react-app-rewired

We want to avoid making these kind of changes in aem-clientlib-generator since it would clash with webpack or other build-tools.

@ittaibaratz
Copy link
Author

Thanks @ifahrentholz , I will consider your suggestions.

@ChazUK
Copy link

ChazUK commented Mar 9, 2022

@ittaibaratz did you ever find a solution to this? I am having a similar problem with Angular. My clientlib builds and compiles the SCSS, updates the import paths relative to the build, then aem-clientlib-generator moves the files which then breaks the relative linking.

@kevinolivar
Copy link

kevinolivar commented Mar 25, 2022

Sorry for reviving this topic :-)

Got a similar issue. I am using remixicon (web font usage) and aem clientlib updates my font face URL by adding 'clientlib-site/css/'

From remixicon.css

@font-face {
  font-family: "remixicon";
  src: url('remixicon.eot?t=1590207869815'); /* IE9*/
  src: url('remixicon.eot?t=1590207869815#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url("remixicon.woff2?t=1590207869815") format("woff2"),
  url("remixicon.woff?t=1590207869815") format("woff"),
  url('remixicon.ttf?t=1590207869815') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('remixicon.svg?t=1590207869815#remixicon') format('svg'); /* iOS 4.1- */
  font-display: swap;
}

From site.css (generated by aem clientlib)

@font-face {
  font-family: "remixicon";
  src: url('clientlib-site/css/remixicon.eot?t=1590207869815'); /* IE9*/
  src: url('clientlib-site/css/remixicon.eot?t=1590207869815#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url("clientlib-site/css/remixicon.woff2?t=1590207869815") format("woff2"),
  url("clientlib-site/css/remixicon.woff?t=1590207869815") format("woff"),
  url('clientlib-site/css/remixicon.ttf?t=1590207869815') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
  url('clientlib-site/css/remixicon.svg?t=1590207869815#remixicon') format('svg'); /* iOS 4.1- */
  font-display: swap;
}

I tried rewriting the URL of the font-face in webpack because AEM needs 'resources' as for public assets. However, again, clientlib appends 'clientlib-site/css' (path relative to the css file, I guess)

I also tried to create a clientlib-font (I did those 3 configurations: 1. css and resources folders 2. css containing all css and fonts 3. resources folder with all css and fonts) but same, AEM changed the font-face url.

Is there a way to tell clientlib to not rewrite the url of specific files?
Is there good AEM practice to import third party fonts without having to copy and extract bits (eg. font-face) of the third party package?

Thanks.

@ifahrentholz ifahrentholz reopened this Mar 27, 2022
@ifahrentholz
Copy link
Member

ifahrentholz commented Apr 3, 2022

Hi @ittaibaratz, Hi @kevinolivar,

you could try to use the base configuration.
Try to copy your whole bundle to the resources folder (do not flatten).
Then you should be able to configure the clientlib generator to resolve your css and js via the base configuration.
Doing this should keep your asset refs as you defined them in your original build and be resolvable.

Example:

assets: {
  js: {
    base: "resources",
    cwd: `path/to/dist`,
    files: ["**/*.js"],
    flatten: false,
  },
  css: {
    base: "resources",
    cwd: `path/to/dist`,
    files: ["**/*.css"],
    flatten: false,
  },
  resources: {
    cwd: `path/to/dist`,
    files: ["**/*.*"],
    flatten: false,
    ignore: ["**/*.js", "**/*.css"],
  },
},

@ifahrentholz
Copy link
Member

I'll close this issue since there is no response.

@kevinolivar
Copy link

kevinolivar commented May 28, 2022

Hi @ifahrentholz,

yeah sorry for that. Actually, I solved that via webpack. Eg. copying the font into the resources folder and "resolve" (string replace) path directly.

const remixiconCss = {
  from: path.resolve(__dirname, './node_modules/remixicon/fonts/remixicon.css'),
  to: './clientlib-icons/css/',
  transform(content) {
    return content
      .toString()
      .replace(/remixicon\./gi, '../resources/remixicon.')
  },
}
const remixiconFonts = {
  from: path.resolve(__dirname, './node_modules/remixicon/fonts'),
  to: './clientlib-icons/resources/',
  globOptions: {
    ignore: [
      '**/remixicon.css',
      '**/remixicon.less',
      '**/remixicon.svg',
      '**/remixicon.symbol.svg',
    ],
  },
}
new CopyWebpackPlugin({
      patterns: [
        ...remixicon,
      ]
})

I may give it a shot with the 'base' option of the clientlib generator.

Thanks anyway!

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

No branches or pull requests

5 participants