title: Webpack for Storybook: Module not found for ts files with .web, .ios or .android extenstions
body: <p>I am trying to use Storybook, with expo and react-native-web.  Whenever I try to use an expo module I am getting the following error</p>
  
  <pre><code>ERROR in ./node_modules/expo-linear-gradient/build/LinearGradient.js
  Module not found: Error: Can't resolve './NativeLinearGradient' in '/Fleyver/front/node_modules/expo-linear-gradient/build'
   @ ./node_modules/expo-linear-gradient/build/LinearGradient.js 1:1373-1406
  </code></pre>
  
  <p>The file that it cannot resolve has multiple extensions for .web.ts, .ios.ts and .android.ts, but there is no straight .ts extenstion</p>
  
  <p>Being a beginner I am struggling with where to begin to fix this problem.  I am using this boilerplate to get started and everything works up until the expo modules</p>
  
  <p><a href="https://github.com/Naturalclar/expo-typescript-starter" rel="nofollow noreferrer">https://github.com/Naturalclar/expo-typescript-starter</a></p>
  
  <p>webpack.config.js</p>
  
  <pre><code>const path = require('path');
  const threadLoader = require('thread-loader');
  const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
  
  const jsWorkerCommonOptions = {
    workers: 2,
    workerParallelJobs: 50,
    poolParallelJobs: 50
  };
  
  const babelWorkerOptions = {
    ...jsWorkerCommonOptions,
    name: 'babel-pool'
  };
  
  const tsWorkerOptions = {
    ...jsWorkerCommonOptions,
    name: 'ts-pool'
  };
  
  module.exports = ({ config, mode }) =&gt; {
    if (mode !== 'PRODUCTION') {
      threadLoader.warmup(babelWorkerOptions, ['babel-loader']);
      threadLoader.warmup(tsWorkerOptions, ['ts-loader']);
    }
    config.module.rules.push({
      test: /\.tsx?$/,
      exclude: /node_modules/,
      use: [
        { loader: 'cache-loader' },
        { loader: 'thread-loader', options: tsWorkerOptions },
        {
          loader: 'ts-loader',
          options: {
            experimentalWatchApi: true,
            transpileOnly: true,
            happyPackMode: true
          }
        },
        { loader: 'react-docgen-typescript-loader' }
      ]
    });
  
    // type-checking
    config.plugins.push(
      new ForkTsCheckerWebpackPlugin({ checkSyntacticErrors: true })
    );
  
    config.module.rules.push({
      test: /\.jsx?$/,
      include: [
        path.resolve(__dirname, '../node_modules/react-native-paper'),
        path.resolve(__dirname, '../node_modules/react-native-elements'),
        path.resolve(__dirname, '../node_modules/react-native-safe-area-view'),
        path.resolve(__dirname, '../node_modules/react-native-vector-icons'),
        path.resolve(__dirname, '../node_modules/@expo/vector-icons'),
        path.resolve(__dirname, '../node_modules/expo-linear-gradient'),
        path.resolve(__dirname, '../node_modules/react-native-ratings'),
        path.resolve(__dirname, '../node_modules/react-native-status-bar-height')
      ],
      use: [
        { loader: 'cache-loader' },
        { loader: 'thread-loader', options: babelWorkerOptions },
        {
          loader: 'babel-loader?cacheDirectory?true',
          options: {
            presets: [
              'module:metro-react-native-babel-preset',
              '@babel/preset-flow'
            ]
          }
        }
      ]
    });
    // react-native を import している箇所を react-native-web に変換
    config.resolve.alias['react-native$'] = require.resolve('react-native-web');
  
    config.resolve.alias['@expo/vector-icons'] = path.resolve(
      __dirname,
      '../node_modules/react-native-vector-icons'
    );
  
    // .ts, .tsx を含めるように追加
    config.resolve.extensions.push(
      '.ts',
      '.tsx'
    );
    return config;
  };
  </code></pre>
  
  <p>package.json</p>
  
  <pre><code>{
    "main": "node_modules/expo/AppEntry.js",
    "scripts": {
      "start": "expo start",
      "android": "expo start --android",
      "ios": "expo start --ios",
      "eject": "expo eject",
      "test": "node ./node_modules/jest/bin/jest.js --watchAll",
      "lint": "eslint . --ext '.ts, .tsx'",
      "type-check": "tsc --noEmit",
      "new": "scaffdog generate",
      "storybook": "start-storybook -h 192.168.1.64 -p 9001 -c .storybook -s .storybook/assets",
      "storybook:build": "build-storybook -c .storybook -s .storybook/assets",
      "klank": "klank storybook-static/index.html"
    },
    "jest": {
      "preset": "jest-expo"
    },
    "dependencies": {
      "@expo/react-native-action-sheet": "^3.0.3",
      "@expo/samples": "3.0.3",
      "expo": "^34.0.4",
      "expo-asset": "^6.0.0",
      "expo-camera": "~6.0.0",
      "expo-font": "~6.0.1",
      "expo-linear-gradient": "~6.0.0",
      "klank": "^0.0.5",
      "react": "16.8.6",
      "react-native": "https://github.com/expo/react-native/archive/sdk-34.0.0.tar.gz",
      "react-native-extended-stylesheet": "^0.12.0",
      "react-native-linear-gradient": "^2.5.6",
      "react-native-paper": "^2.16.0",
      "react-native-vector-icons": "^6.6.0",
      "react-navigation": "^3.11.1"
    },
    "devDependencies": {
      "@babel/core": "^7.5.5",
      "@emotion/core": "^10.0.15",
      "@storybook/addon-actions": "^5.1.10",
      "@storybook/addon-info": "^5.1.10",
      "@storybook/addon-knobs": "^5.1.10",
      "@storybook/addon-options": "^5.1.10",
      "@storybook/addon-storyshots": "^5.1.10",
      "@storybook/addon-viewport": "^5.1.10",
      "@storybook/react": "^5.1.10",
      "@storybook/theming": "^5.1.10",
      "@types/expo": "^32.0.13",
      "@types/expo__vector-icons": "^9.0.1",
      "@types/jest": "^24.0.17",
      "@types/react": "^16.8.25",
      "@types/react-native": "^0.60.3",
      "@types/react-navigation": "^3.0.8",
      "@types/react-test-renderer": "^16.8.3",
      "@types/storybook__addon-actions": "^3.4.3",
      "@types/storybook__addon-knobs": "^5.0.3",
      "@types/storybook__react": "^4.0.2",
      "@typescript-eslint/eslint-plugin": "^1.13.0",
      "@typescript-eslint/parser": "^1.13.0",
      "babel-loader": "^8.0.6",
      "babel-preset-expo": "^5.2.0",
      "cache-loader": "^4.1.0",
      "eslint": "^6.1.0",
      "eslint-config-airbnb": "^17.1.1",
      "eslint-config-prettier": "^6.0.0",
      "eslint-plugin-import": "^2.18.2",
      "eslint-plugin-jsx-a11y": "^6.2.3",
      "eslint-plugin-prettier": "^3.1.0",
      "eslint-plugin-react": "^7.14.3",
      "eslint-plugin-typescript": "^0.14.0",
      "fork-ts-checker-webpack-plugin": "^1.5.0",
      "jest-expo": "^34.0.0",
      "metro-react-native-babel-preset": "^0.55.0",
      "node-fetch": "^2.6.0",
      "prettier": "^1.18.2",
      "react-art": "16.8.6",
      "react-docgen-typescript-loader": "^3.1.0",
      "react-dom": "16.8.6",
      "react-native-elements": "^1.1.0",
      "react-native-web": "^0.11.5",
      "react-test-renderer": "^16.8.6",
      "redux-logger": "^3.0.6",
      "scaffdog": "^0.1.2",
      "thread-loader": "^2.1.2",
      "ts-loader": "^6.0.4",
      "tslint": "^5.18.0",
      "typescript": "^3.5.3"
    },
    "private": true
  }
  
  </code></pre>
  
  <p>When I run the various components in the app using any of the expo start methods, including <code>expo start --web</code>   I can see the components, however Storybook fails to load.  I am expecting to see the components load in a story for Storybook</p>
  
  <p>Any advice would be greatly appreciated</p>