storybookjs / addon-react-native-web

Build react-native-web projects in Storybook for React
MIT License
83 stars 24 forks source link

[Bug] build storybook failed with library type:module #71

Closed YOEL311 closed 1 year ago

YOEL311 commented 1 year ago

Describe the bug

I have written the library to be used in my company the library works as well in my react-native app

it also works without any problem in the react-native storybook app, but when I built an app for the storybook web app the build failed with this error

ModuleNotFoundError: Module not found: Error: Can't resolve './button' in '/Users/#####/node_modules/###/components/lib/src/components'
Did you mean 'index.js'?
BREAKING CHANGE: The request './button' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').

the library import with this Syntax

export * from './button'; or import ButtonCore from './core';

but the web app needs

export * from './button.js'; or import ButtonCore from './core.js';

how I can resolve this error without rewriting all library

dannyhw commented 1 year ago

This seems like a classic esm vs commonjs issue but what version of storybook are you running?

If those errors are from ts there are also rules you can add to typescript which allow you to import without the js extension.

YOEL311 commented 1 year ago

hey @dannyhw thanks for your response

my storybook version is 6

in my project that works (import without the js extension) it works only from my package in the ReactNative app It happens only in web app

attached my package.json file

{
  "name": "CoreStorybook",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint . --ext .js,.jsx,.ts,.tsx",
    "update-stories": "sb-rn-get-stories --config-path .ondevice",
    "prestart": "yarn update-stories",
    "storybook-watcher": "sb-rn-watcher --config-path .ondevice",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "dependencies": {
    "@babel/plugin-proposal-export-namespace-from": "7.18.9",
    "@----/components": "0.0.34",                           //<the component is from this package
    "@---/theme": "1.0.98",
    "@react-native-async-storage/async-storage": "^1.17.3",
    "@react-native-community/datetimepicker": "^6.7.1",
    "@react-native-community/slider": "4.3.3",
    "@react-native-cookies/cookies": "6.2.1",
    "react": "18.2.0",
    "react-dom": "^18.2.0",
    "react-native": "0.71.4",
    "react-native-gesture-handler": "2.13.4",
    "react-native-linear-gradient": "2.8.3",
    "react-native-reanimated": "2.17.0",
    "react-native-safe-area-context": "4.4.1",
    "react-native-svg": "14.0.0",
    "react-native-web": "0.18.10",
    "react-native-web-linear-gradient": "1.1.2"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native-community/eslint-config": "^3.2.0",
    "@react-native/eslint-config": "^0.72.1",
    "@react-native/metro-config": "0.73.2",
    "@storybook/addon-actions": "^6.5.14",
    "@storybook/addon-controls": "^6.5.14",
    "@storybook/addon-essentials": "^6.5.14",
    "@storybook/addon-links": "^6.5.14",
    "@storybook/addon-ondevice-actions": "^6.5.1",
    "@storybook/addon-ondevice-backgrounds": "^6.5.1",
    "@storybook/addon-ondevice-controls": "^6.5.1",
    "@storybook/addon-ondevice-notes": "^6.5.1",
    "@storybook/addon-react-native-web": "^0.0.19",
    "@storybook/builder-webpack5": "^6.5.16",
    "@storybook/manager-webpack5": "^6.5.16",
    "@storybook/react": "^6.5.14",
    "@storybook/react-native": "^6.5.1",
    "@storybook/testing-library": "^0.0.13",
    "@tsconfig/react-native": "^2.0.2",
    "@types/jest": "^29.2.1",
    "@types/react": "^18.0.24",
    "@types/react-native": "^0.70.6",
    "@types/react-test-renderer": "^18.0.0",
    "@typescript-eslint/eslint-plugin": "^5.37.0",
    "@typescript-eslint/parser": "^5.37.0",
    "babel-jest": "^29.2.1",
    "babel-loader": "^8.2.4",
    "babel-plugin-react-docgen-typescript": "^1.5.1",
    "babel-plugin-react-native-web": "^0.18.10",
    "eslint": "^8.19.0",
    "eslint-import-resolver-custom-alias": "^1.3.2",
    "eslint-plugin-import": "^2.29.0",
    "eslint-plugin-justinanastos": "1.3.1",
    "eslint-plugin-simple-import-sort": "^10.0.0",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "0.73.8",
    "prettier": "^2.4.1",
    "react-native-svg-transformer": "1.1.0",
    "react-test-renderer": "18.2.0",
    "storybook-react-context": "0.6.0",
    "typescript": "4.8.4"
  },
  "resolutions": {
    "@leumi/theme": "1.0.98",
    "react": "18.2.0",
    "react-devtools-core": "4.25.0",
    "react-native": "0.71.4",
    "react-native-safe-area-context": "4.4.1",
    "react-native-reanimated": "2.17.0"
  },
  "jest": {
    "preset": "react-native"
  }
}
dannyhw commented 1 year ago

@YOEL311 are you able to make a minimal reproduction in a public repository? I've never really ran into this problem before so I'd have to look closer. Though its sounding like a configuration thing.

You could also try some of the solutions here https://github.com/storybookjs/storybook/issues/11587

YOEL311 commented 1 year ago

@dannyhw I can`t because the library that I use is under a private npm registry

dannyhw commented 1 year ago

@YOEL311 you don't need to use that same library, just setup a project with ESM and see if it has the same issue.

YOEL311 commented 1 year ago

@dannyhw I will work on it But it might take me some time

Thanks

But I can show it to you in a joint conversation If you are interested of course

dannyhw commented 1 year ago

@YOEL311 sorry I'm travelling and working right now so my free time is kinda limited. Normally I would but for now I can't really take a call.

YOEL311 commented 1 year ago

@dannyhw

ok this is a public components library https://github.com/YOEL311/componentsPublic it also in npm https://www.npmjs.com/package/test-package-yoel-test

use it in the project

https://github.com/YOEL311/storybookPublic/blob/87c367d2f55b1c7bc37e3a6be184312dcc9b9fd6/components/Buttons/ButtonLess.tsx#L2

this is the storyboard project

https://github.com/YOEL311/storybookPublic

Thanks

to reproduce issue git clone https://github.com/YOEL311/storybookPublic cd storybookPublic yarn yarn start //work on android or ios yarn storybook //not work

dannyhw commented 1 year ago

Ok thanks I will take a look soon

YOEL311 commented 1 year ago

I try to add the js extension as a manual I made it in tag 35 in my library you can see here

https://github.com/YOEL311/componentsPublic/releases/tag/v0.0.35

but now I got another error

ModuleParseError: Module parse failed: Unexpected token (5:4)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| function ButtonLess({ text, width }) {
|   return (
>     <ButtonCore {...{ width }} gradientColors={['red', 'green']}>
|       <>
|         <View style={{ marginRight: 10 }} />

I also tried to change the type of library to CommonJS in the package.json and tsconfig.jsonfiles but I got an error with 36 tag

commit https://github.com/YOEL311/componentsPublic/commit/6477bcef378ca0983c2ae40412ae78d6cd8b07c0 tag https://github.com/YOEL311/componentsPublic/releases/tag/v0.0.36

ModuleParseError: Module parse failed: Unexpected token (7:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const core_1 = tslib_1.__importDefault(require("./core"));
| function ButtonLess({ text, width }) {
>     return (<core_1.default {...{ width }} gradientColors={['red', 'green']}>
|       <>
|         <react_native_1.View style={{ marginRight: 10 }}/>
    at handleParseError (/Users/yoeln/LeumiProjects/storybookPublic/node_modules/@storybook/builder-webpack5/node_modules/webpack/lib/NormalModule.js:982:19)
dannyhw commented 1 year ago

That doesn't look like an issue with esm, its more likely that your componentsPublic isn't transpiled for web, you can add that package to be transpiled.

dannyhw commented 1 year ago

you also have three sets of config for addon-react-native-web, it should only appear once

image

like this

  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    {
      name: '@storybook/addon-react-native-web',
      options: {
        modulesToAlias: {
          'react-native-linear-gradient': 'react-native-web-linear-gradient',
        },
        modulesToTranspile: ['react-native-reanimated', 'test-package-yoel-test'],
        babelPlugins: [
          '@babel/plugin-proposal-export-namespace-from',
          'react-native-reanimated/plugin',
        ],
      },
    },
  ],
dannyhw commented 1 year ago

having a little bit of trouble getting esm working for you but I'm looking into it

YOEL311 commented 1 year ago

@dannyhw Hi, I solved it by adding Babel before publishing the package, it's strange that for react native it worked without it and you have to add it for the web

You can see the fix in this commit https://github.com/YOEL311/componentsPublic/commit/2a50faf73993858d21fc36f62b4395fe4ffd7dcb now it works on this version

"test-package-yoel-test": "0.0.42"

dannyhw commented 1 year ago

That's actually quite normal, metro will transpile everything whereas with webpack node modules are ignored in transpilation and must be explicity included.