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

Add support for file extension placeholder and function in output.entryFileNames option #3107

Closed
awmottaz opened this issue Sep 10, 2019 · 11 comments · Fixed by #3116
Closed

Comments

@awmottaz
Copy link

awmottaz commented Sep 10, 2019

See also

Feature Use Case

If I enable the preserveModules option, I get undesired filenames in the build output. For example, I might name a CSS module the same as a component with only the file extension distinguishing the two files:

src/
  FooComponent.jsx
  FooComponent.scss

Today, the output from using preserveModules: true will give me

dist/
  FooComponent.js
  FooComponent2.js

Feature Proposal

Add a placeholder for the file extension that can be used in the output.entryFileNames template option, and add support for specifying a function, so that if I have this configuration:

export default {
  input: 'src/FooComponent.jsx',
  output: {
    dir: 'dist',
    format: 'esm',
    entryFileNames: id => /\.(jsx?|tsx?)$/.test(id) ? '[name].js' : '[name].[ext].js'
  },
  preserveModules: true,
  // other options
}

I get this build output:

dist/
  FooComponent.js
  FooComponent.scss.js
@Andarist
Copy link
Member

Im not using rollup as general purpose bundler, i just build npm libraries with it. So I’ wondering - what’s the output when u dont use preserveModules and u handle scss etc through rollup?

@awmottaz
Copy link
Author

@Andarist

what’s the output when u dont use preserveModules and u handle scss etc through rollup?

If the preserveModules option is not provided, Rollup will be bundling the code (it's default behavior). I would need to modify the output options to account for this:

export default {
  input: 'src/FooComponent.tsx',
  output: {
    file: 'dist/FooComponent.js',
    format: 'esm'
  },
  // other options
}

The output from the build would just be

dist/
  FooComponent.js

with the SCSS module included within the dist/FooComponent.js file.

@Andarist
Copy link
Member

Interesting - I would have thought that SCSS would produce a separate CSS file 🤔

@awmottaz
Copy link
Author

It can, depends on how CSS modules are set up.

Regardless, the requested feature is still useful for all kinds of workflows beyond the specific example I gave.

@Andarist
Copy link
Member

I'm just wondering about the exact workflow here - so the solution can be implemented with all things in mind. In this case, it's somewhat weird for me that SCSS can compile down to regular JS instead of emitting a CSS which in turn would be turned into a "virtual" JS file (if needed).

It is what it is though and even might be a good thing, I certainly haven't spent that much time thinking about this.

Seems to me that in this case, we should be able to do a "good thing" by default - supporting [ext] is ofc still on the table. It shouldn't be needed every time though, only when one really wants to change the default pattern.

By doing a good thing here I mean special casing known js~ extensions (js,jsx,ts,tsx) and using current pattern for them, but using '[name]-[ext].js' (or '[name].[ext].js') for everything else. WDYT? cc @lukastaegert

@awmottaz
Copy link
Author

I'm just wondering about the exact workflow here - so the solution can be implemented with all things in mind.

I'm working on a component library, the setup is like this:

src/
  index.ts # re-exports the components
  components/
    Foo/
      Foo.tsx
      Foo.scss
    Bar/
      Bar.tsx
      Bar.scss

The *.scss files are imported by the *.tsx files as CSS modules. In the build, I'm using a PostCSS plugin to extract the styles into a common index.css file, and each of the *.scss files is converted to a JS module which exports an object whose keys are classnames defined in the *.scss to the generated scoped classnames. The ideal output would look like this:

dist/
  index.js # transformed entry point, re-exports the components
  index.css # generated styles with scoped classnames
  components/
    Foo/
      Foo.js
      Foo.scss.js
    Bar/
      Bar.js
      Bar.scss.js

As an example, if the Foo.scss source code defines styles for the classes .outer and .inner, the styles would be emitted as part of the dist/index.css file and the Foo.scss.js file in the output might look like this:

var css = {"outer": "Foo__outer_8dF76", "inner": "Foo_inner_kjLU7"};

export default css;

@Andarist
Copy link
Member

Ok, I get it now - so the CSS asset gets emitted, just "elsewhere" (a single index.css at root or smth). Thanks for clarifying this.

@awmottaz
Copy link
Author

You're welcome!

Another use-case is when using SVGR which transforms *.svg images into React components directly (no other emitted assets). It would be nice to name those *.svg.js in the output.

@Andarist
Copy link
Member

I've prepared a PR fixing the original issue here - #3116

@bhabgs
Copy link

bhabgs commented Nov 5, 2019

I'm just wondering about the exact workflow here - so the solution can be implemented with all things in mind.

I'm working on a component library, the setup is like this:

src/
  index.ts # re-exports the components
  components/
    Foo/
      Foo.tsx
      Foo.scss
    Bar/
      Bar.tsx
      Bar.scss

The *.scss files are imported by the *.tsx files as CSS modules. In the build, I'm using a PostCSS plugin to extract the styles into a common index.css file, and each of the *.scss files is converted to a JS module which exports an object whose keys are classnames defined in the *.scss to the generated scoped classnames. The ideal output would look like this:

dist/
  index.js # transformed entry point, re-exports the components
  index.css # generated styles with scoped classnames
  components/
    Foo/
      Foo.js
      Foo.scss.js
    Bar/
      Bar.js
      Bar.scss.js

As an example, if the Foo.scss source code defines styles for the classes .outer and .inner, the styles would be emitted as part of the dist/index.css file and the Foo.scss.js file in the output might look like this:

var css = {"outer": "Foo__outer_8dF76", "inner": "Foo_inner_kjLU7"};

export default css;

I want to know, how to setting .tsx compile

@frank-dspeed
Copy link
Contributor

Closed by: #3658

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

Successfully merging a pull request may close this issue.

4 participants