lukeed/clsxPublic

A tiny (239B) utility for constructing `className` strings conditionally.

Odd Webpack issue dropping clsx

LE

This is quite hard to debug as it's part of a Storybook build process. `clsx` works fine when in development mode - however when we run `build-storybook` it seems to drop the module.

``` Cannot read property 'default' of undefined TypeError: Cannot read property 'default' of undefined at http://127.0.0.1:8080/main.4e9c45778b78ebc1cf6a.bundle.js:1:39326 at Ih (http://127.0.0.1:8080/vendors~main.4e9c45778b78ebc1cf6a.bundle.js:85:59571) ``` Piece of compiled JS from webpack: ``` composedClassName=(0,_clsx.default)("a-button","a-button--".concat(variant),(_clsx={"a-button--transparent":isTransparent,"a-button--form":isForm&&(isPrimary||isSecondary),"a-button--full-width":isFullWidth,"a-button--input":isInput},(0,_defineProperty2.default)(_clsx,"a-button--".concat(icon),icon&&!isTransparent&&!isFullWidth),(0,_defineProperty2.default)(_clsx,"is-disabled",isDisabled),_clsx),className); ```

I've narrowed it down to this:

``` const composedClassName = clsx( 'a-button', `a-button--${variant}`, { [`a-button--${icon}`]: icon && !isTransparent && !isFullWidth, 'a-button--transparent': isTransparent, 'a-button--form': isForm && (isPrimary || isSecondary), 'a-button--full-width': isFullWidth, 'a-button--input': isInput, 'is-disabled': isDisabled, }, className ); ``` Which seems to happen when combining the `[key]` method with regular strings... so, while the above fails, this succeeds on placing it in its own object. ``` const composedClassName = clsx( 'a-button', `a-button--${variant}`, { [`a-button--${icon}`]: icon && !isTransparent && !isFullWidth, }, { 'a-button--transparent': isTransparent, 'a-button--form': isForm && (isPrimary || isSecondary), 'a-button--full-width': isFullWidth, 'a-button--input': isInput, 'is-disabled': isDisabled, }, className ); ```

I don't suppose you have any idea of why this might be happening?

Babel config looks like: ``` const useModules = process.env.BUILD_FORMAT === 'esm';

module.exports = { env: { test: { presets: ['@babel/preset-react', '@babel/preset-env'], }, development: { presets: ['@babel/preset-react', '@babel/preset-env'], }, production: { presets: [ '@babel/preset-react', [ '@babel/preset-env', { modules: useModules ? false : 'commonjs', }, ], ], plugins: [ 'babel-plugin-optimize-clsx', '@babel/plugin-transform-react-constant-elements', [ '@babel/plugin-transform-runtime', { corejs: false, helpers: true, regenerator: true, useESModules: useModules, }, ], ], }, }, }; ``` I have tried removing the `babel-plugin-optimize-clsx` plugin, but it makes no difference. Not that it makes any difference, but `classnames` package works as expected - so I'm only guessing it's something to do with `clsx` itself.

  1. TR

    Hi @leepowellcouk Do you use mjs extension for your modules?

  2. leepowelldevmentioned6 years ago on GitHub

  3. leepowelldevsubscribed6 years ago on GitHub

  4. LE
    Author

    No we don't. We build to a commonjs format in a `lib` directory and a modules format in a `esm` directory - then use `main` and `module` in `package.json` to point to the entry point for each.

  5. TR

    you webpack is most likely processing modules from node_modules try to do something like this ```js webpack,config.module.rules.push({ test: /\.[tj]sx?$/, exclude: /(node_modules\/(?!(@YOUR_COMPANY_NAMESPACE)\/))/, use: [BABEL_CONFIG], }); ```

  6. LU

    Hey,

    I think I'd have to see the storybook config. Can you elaborate more on "works fine in development" – I'm not sure if this means application development (eg, PWA or CRA or similar) or storybook development.

    Thanks

  7. LE
    Author

    After more debugging, it seems our babel config was converting to `commonjs` modules via `babel-preset-env` - not sure why that would have caused the issue, but setting it to `false` has resolved it.

  8. LU

    Was that specific to `build-storybook`?

    I usually tell Babel to `modules: false` because transforming/handling module syntax is Webpack/Rollup's job when you're using it – not Babel's.

  9. LE
    Author

    No, sorry, this was storybook picking up our babel config.

  10. LU

    But your babel config wasn't being picked up during development?

    Sorry, I'm confused. I feel like I have 15% of the information. Not even sure if you're suggesting that this is a `clsx` issue still?

  11. LE
    Author

    Sure, sorry, been a manic couple of days. No, I don't think this is an issue with `clsx` - we have a babel config for building out our UI library (which storybook is used to document), it transpiles our es based source into 2 distros for consumption - commonjs and es6 modules.

    During development (using `start-storybook`) storybook uses the `create-react-app` scripts internally to do any compiling and doesn't use our babel config at all. However, it seems when we run `build-storybook` it was reading our babel config - so the config we have to run our production UI library babel build was also being used for the production storybook build - it was here that it was trying to do the conversion to `commonjs` modules via `@babel/preset-env` - I haven't had any further time to dig into why this was causing the issue - but I'm fairly confident it was a configuration conflict rather than an issue with `clsx`.

  12. leepowelldevclosed6 years ago on GitHub

  13. LU

    Okay, got it 👍 I don't really have much experience with those tools so I'm afraid I can't help you out much here. Sorry & good luck!