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

copy fonts #121

Open
asicfr opened this issue Apr 10, 2018 · 9 comments
Open

copy fonts #121

asicfr opened this issue Apr 10, 2018 · 9 comments

Comments

@asicfr
Copy link

asicfr commented Apr 10, 2018

Hi, i know that you do not encourage the use of copy, but i have a tricky need.
I have a node_module with a css file and relative font urls :
@font-face{font-family:"Avenir";src:url("./fonts/avenir-lighter.woff") format("woff")}

My app uses Nextjs and with style-loader + css-loader, my css module is well integrated to the output /.next/static/style.css but font files url are not copied magically to that folder.

So i want to use postcss-url to copy all fonts files to /.next/static/ and adapt url to point to that files.
I try that :

module.exports = {
  plugins: [
    require('postcss-url')({
      url: 'copy',
      basePath: `${path.resolve('node_modules/my-styleguide')}/dist/build/`,
      assetsPath: '/.next/static/',
    }),
  ]
};

Sadly, it doesn't work and i get the following error :
These relative modules were not found:

  • ../../../../.next/static/fonts/avenir-bold-black-heavy.woff in ./node_modules/my-styleguide/dist/build/styleguide.css

Have you got any idea ?

Thx

@mojavelinux
Copy link

Here's what I use. First, I require typeface fonts from npm (e.g., https://yarnpkg.com/en/package/typeface-roboto). Then I configure the task as follows:

const postcssPlugins = [ 
  postcssUrl([
    {
      filter: '**/~typeface-*/files/*',
      url: (asset) => {
        const relpath = asset.pathname.substr(1)
        const abspath = path.resolve('node_modules', relpath)
        const basename = path.basename(abspath)
        const destpath = path.join(dest, 'font', basename)
        if (!fs.pathExistsSync(destpath)) fs.copySync(abspath, destpath)
        return path.join('..', 'font', basename)
      },
    },
  ]),
]

This puts the fonts into the "font" folder inside the dest directory, where I can bundle them with my app.

@vatson
Copy link

vatson commented Jul 19, 2019

@mojavelinux a little bit tricky but very helpful! Kudo.

One note, please add that you use fs-extra package

@frederikhors
Copy link

I think we should write @mojavelinux solution in Readme, somewhere.

Thanks @mojavelinux.

@Roboe
Copy link

Roboe commented May 1, 2020

I think this qualifies as a bug. Enabling the useHash option works just fine:

module.exports = {
  // inherited 'to' from the postcss-cli command flags
  plugins: [
    require('postcss-import')(),
    require('postcss-url')({
      url: 'copy',
      assetsPath: 'static',
      useHash: true,
    }),
    ...otherPlugins,
  ],
}

Imported files were copied to the assetsPath inside the to folder and correctly referenced in the processed CSS.

@shishkin
Copy link

On top of @mojavelinux 's solution I had to ensure destpath directory exists and provide dest path pointing to the PostCSS output directory relative to the project root.

Is there any way to get the PostCSS out directory inside the custom url function?

@mojavelinux
Copy link

mojavelinux commented Aug 16, 2022

Here's what I did:

postcssUrl([
  {
    url: (asset) => {
      const relpath = asset.pathname.substr(1)
      const abspath = require.resolve(relpath)
      const basename = ospath.basename(abspath)
      const destpath = ospath.join(dest, 'font', basename)
      if (!fs.pathExistsSync(destpath)) fs.copySync(abspath, destpath)
      return path.join('..', 'font', basename)
    },
  },
]),

(I just realized I shared exactly the same snippet above).

@shishkin
Copy link

@mojavelinux maybe I miss something here, but where does dest variable come from?

@mojavelinux
Copy link

It's the value passed into the function that is handling writing the processed CSS. In my case, I'm using postCSS in a vinyl-fs pipeline. So dest is the vinyl-fs dest target.

@l-outsider
Copy link

@mojavelinux
hello, I use this way but my url path become base64 code, I want to use relative path string, how can I use rebase when url is a function.

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

7 participants