create-react-library icon indicating copy to clipboard operation
create-react-library copied to clipboard

Adding assets

Open teehtheg opened this issue 4 years ago • 21 comments

Is it possible to add assets to the library such as fonts or images?

Apparently create-react-app provides this feature in two different ways:

  • explicit import in your typescript / javascript code
  • the public folder

Would one of these approaches be feasible for create-react-library aswell?

teehtheg avatar Apr 02 '20 17:04 teehtheg

You should be able to import image files directly into your library from JS / TS. We're using this under the hood https://github.com/sormy/rollup-plugin-smart-asset

transitive-bullshit avatar Apr 03 '20 00:04 transitive-bullshit

Oke, thats good to know! But what about fonts?

teehtheg avatar Apr 03 '20 07:04 teehtheg

If you list the extensions you'd like to bundle, I can add them to microbundle for you.

transitive-bullshit avatar Apr 03 '20 23:04 transitive-bullshit

From the top of my head, I see two options:

  1. Use the plugin you're already using and adding the required file extensions to also handle fonts. I would recommend adding the following extensions to be on the safe side: [".eot", ".ttf", ".woff", ".svg", ".woff2"]

  2. Use rollup-plugin-copy and define a specific folder (e.g. "/assets") which will be copied into the build. This approach would not be restricted to certain file extensions, but it is not that "smart" in that it is copying over all files in this folder, and not just the ones which are referenced from your TS / JS code.

What's your opinion about that?

By the way: I really appreciate your willingness to extend / adjust your tool!

teehtheg avatar Apr 04 '20 12:04 teehtheg

That would also be a big feature for me.

tbelch-at-eHealth-Tec avatar May 20 '20 03:05 tbelch-at-eHealth-Tec

Any news on this? Is it possible?

kzviagina avatar Jul 06 '20 14:07 kzviagina

In case someone needs to copy assets(fonts and images) referenced in css, you can add the following to microbundle-crl in postcss plugings section:

import postcssCopy from 'postcss-copy';

postcss({
    plugins: [
        ...
        postcssCopy({
            dest: dirname(options.output),
            template: 'assets/[hash].[ext][query]',
        }),
        ...
    ],
})

I also created PR with this change https://github.com/transitive-bullshit/microbundle/pull/3

kzviagina avatar Jul 12 '20 20:07 kzviagina

Hey there, is there a workaround to be able to bundle fonts currently? I'm trying to do this now with the typescript version of create-react-library and getting an error.

Here's my typings.d.ts file:

declare module '*.woff';
declare module '*.woff2';

Here's my fonts.ts file:

import { createGlobalStyle } from 'styled-components';
import FFMarkBoldWoff from './ff-mark-bold.woff';

export default createGlobalStyle`
    @font-face {
        font-family: 'FF Mark';
        src: local('FF Mark'), local('FFMark'),
        url(${FFMarkBoldWoff2}) format('woff2'),
        url(${FFMarkBoldWoff}) format('woff');
        font-weight: 700;
        font-style: bold;
        font-display: swap;
    }
`;

The compiler complains with:

Error: Unexpected character '' (Note that you need plugins to import files that are not JavaScript)
at /Users/ashok/src/flixed/atoms/src/assets/fonts/ff-mark-bold.woff:1:4
1: wOFFWv��T`�GPOSl�#*�Pj'OS/2TU`uH�;VDMX�m�sXz�cmap�

rajuashok avatar Sep 02 '20 18:09 rajuashok

@rajuashok for now the only way to do this is to fork the repository and add ability to bundle fonts referenced in js. Or alternatively you can reference fonts in css and use the example I mentioned in previous comment.

kzviagina avatar Sep 02 '20 21:09 kzviagina

Hey @kzviagina thanks for the response! Sorry could you elaborate a bit on how to "add the ability to bundle fonts". Are you aware of exactly how to do that?

And if not, in your previous comment where exactly are you adding that snippet of code? There doesn't seem to be a config file for microbundle.

rajuashok avatar Sep 03 '20 00:09 rajuashok

@rajuashok unfortunately it's impossible to "configure" this somehow with create-react-library at the moment. So the only way to make it work with fonts is to fork transitive-bullshit/microbundle, which is used by create-react-library to bundle resources and add functionality, that is required for you (in your case this is bundling fonts from js files). At least this is how I solved it for my case - bundle fonts, referenced in css.

kzviagina avatar Sep 03 '20 10:09 kzviagina

Ah I see. Ok thank you so much that's very helpful!

rajuashok avatar Sep 03 '20 12:09 rajuashok

Hello guys! using @kzviagina code I create a package https://www.npmjs.com/package/microbundle-crl-with-assets, just add it and update all references in your package.json.

rafaelguinho avatar Dec 02 '20 13:12 rafaelguinho

You should be able to import image files directly into your library from JS / TS

Although importing an image file works someway, it's not working for me to use the image in my code.

Using something like…

import iconImage from './images/area-icon.png';

Is translated to a var iconImage = "area-icon~eXbSLfTS.png"; in my UMD bundle, but this is not importing from the proper URL (as it starts from the HTML file).

keul avatar Dec 09 '20 16:12 keul

@keul Have you found a solution for this? I'm having the same problem.

ghost avatar Jan 04 '21 15:01 ghost

@gilsonviana-oowlish I tried multiple approaches, no one applicable to every output format of the bundle.

A good partial approach was using import.meta.url then adding the filename from the import above to it, but this was not working everywhere (import.meta is only for modules).

I ended up by converting the image usage to a CSS background and including a full URL to unpkg in the CSS. Shame on me… but it works. 🤷‍♂️

keul avatar Jan 04 '21 15:01 keul

@keul Thanks for your answer. I ended up using a CDN service like CloudFront, AWS S3, to host my assets.

ghost avatar Jan 13 '21 13:01 ghost

You can export any asset from create-react-library to the create-react-app via two steps.

  1. import libraryAsset from "./asset.svg" Which is going to tell library bundler to add asset to the /dist directory.
  2. const asset = require(`./${libraryAsset}`) Which is going to tell react app bundler to add asset to the /build directory of an app.

Library should then use required asset e.g

<img src={asset}/>

mazurwiktor avatar Feb 02 '21 11:02 mazurwiktor

@mazurwiktor Hi, I tried your solution and it worked like a charm for development. Problem is in deployment it seems like the assets don't resolve properly:

Could not find module in path: 'gluestick-elements/dist/arrow_forward_dark~feBKLjrO.svg' relative to '/node_modules/gluestick-elements/dist/index.modern.js'

CodeSandbox example: https://codesandbox.io/s/gluestick-demo-1c1dl

What's weird is in node_modules I can actually see all the assets have been included and downloaded.

hsyyid avatar Apr 05 '21 17:04 hsyyid

In case someone needs to copy assets(fonts and images) referenced in css, you can add the following to microbundle-crl in postcss plugings section:

import postcssCopy from 'postcss-copy';

postcss({
    plugins: [
        ...
        postcssCopy({
            dest: dirname(options.output),
            template: 'assets/[hash].[ext][query]',
        }),
        ...
    ],
})

I also created PR with this change transitive-bullshit/microbundle#3

based on the above answer I've managed to do it without forking or using the published fork of the fork of the fork in the answer below:

Hello guys! using @kzviagina code I create a package https://www.npmjs.com/package/microbundle-crl-with-assets, just add it and update all references in your package.json.

You can have a postcss.config.js and put this inside it:

module.exports = {
  plugins: {
    'postcss-copy': {dest: 'dist', template: 'assets/[hash].[ext][query]'}
  }
}

But my main problem with those forks was that I get errors regarding files not found and the way they are referenced (the built path). And since I now have a config file I can play with it. In my case I ended up with the following:

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
    'postcss-copy-assets': {base: 'dist'}
    // 'postcss-copy': {dest: 'dist/', template: 'assets/[hash].[ext][query]'}
  }
}

seemingly postcss-copy-assets does a better job and no need to worry about hashes bcs this is the dist of your library, people using it probably use webpack with create-react-app or anuglar or vue or whatever and it'll fix that.

unicornist avatar Oct 28 '21 02:10 unicornist

Hey there, is there a workaround to be able to bundle fonts currently? I'm trying to do this now with the typescript version of create-react-library and getting an error.

Here's my typings.d.ts file:

declare module '*.woff';
declare module '*.woff2';

Here's my fonts.ts file:

import { createGlobalStyle } from 'styled-components';
import FFMarkBoldWoff from './ff-mark-bold.woff';

export default createGlobalStyle`
    @font-face {
        font-family: 'FF Mark';
        src: local('FF Mark'), local('FFMark'),
        url(${FFMarkBoldWoff2}) format('woff2'),
        url(${FFMarkBoldWoff}) format('woff');
        font-weight: 700;
        font-style: bold;
        font-display: swap;
    }
`;

The compiler complains with:

Error: Unexpected character '' (Note that you need plugins to import files that are not JavaScript)
at /Users/ashok/src/flixed/atoms/src/assets/fonts/ff-mark-bold.woff:1:4
1: wOFFWv��T`�GPOSl�#*�Pj'OS/2TU`uH�;VDMX�m�sXz�cmap�

Trying to import custom font and having the same issue. Also aware this library is no longer maintained. But its legacy app. Adding postcss.config.sg as suggested here https://github.com/transitive-bullshit/create-react-library/issues/220#issuecomment-953450786 didn't work. Still getting the same error.

Are there any ways to import the fonts?

resting avatar Feb 02 '23 09:02 resting