Webpacker: react + typescript workflow and error reporting

Created on 8 Sep 2019  ·  14Comments  ·  Source: rails/webpacker

Versions:
"@rails/webpacker": "4.0.2"
gem 'webpacker', '~> 4.x'

After following the docs here https://github.com/rails/webpacker/blob/master/docs/typescript.md and tweaking a bit the typescript loader the installer generated by default I ended up with:

const PnpWebpackPlugin = require('pnp-webpack-plugin');

module.exports = {
  test: /\.(ts|tsx)?(\.erb)?$/,
  use: [
    {
      loader: 'ts-loader',
      options: PnpWebpackPlugin.tsLoaderOptions({
        compilerOptions: {
          jsx: 'react',
          allowSyntheticDefaultImports: true,
        },
      }),
    },
  ],
};

My problem is that when running dev server the output looks like this:

ERROR in /Users/akoskm/Projects/app/javascript/packs/components/products_sidebar/index.tsx
./app/javascript/packs/components/products_sidebar/index.tsx
[tsl] ERROR in /Users/akoskm/Projects/app/javascript/packs/components/products_sidebar/index.tsx(28,63)
      TS2322: Type 'true' is not assignable to type 'string'.

however if I run ./node_modules/.bin/tsc --jsx react -w --allowSyntheticDefaultImports --noEmit in a separate window I get a more detailed error:

$ ./node_modules/.bin/tsc --jsx react -w --allowSyntheticDefaultImports --noEmit
[10:22:49 PM] Starting compilation in watch mode...

app/javascript/packs/components/products_sidebar/index.tsx:28:63 - error TS2322: Type 'true' is not assignable to type 'string'.

28       <SectionContainer headerDetails={DIMENSIONS_AND_WEIGHT} title>
                                                                 ~~~~~

  app/javascript/packs/components/sidebar/sidebar_section/index.tsx:6:3
    6   title: string,
        ~~~~~
    The expected type comes from property 'title' which is declared here on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'

[10:22:53 PM] Found 1 error. Watching for file changes.

Is this how you use typescript with webpacker?
Is there any way to make the webpack-dev-server error reporting as comprehensive as the output from tsc?

bug help wanted

Most helpful comment

Gaurav handles the if and when of all of the releases. I would use what @ShootPassSlam posted above.

All 14 comments

Hey @akoskm,

Can you provide the /packs/components/sidebar/sidebar_section/index.tsx and /packs/components/products_sidebar/index.tsx so I can repo your error messages more closely?

Also, are you starting the dev server with rails server or using another command?

I'm starting the server with make serve which runs some checks before executing bin/rails server. To output looks like this:

[Webpacker] Compiling…
[Webpacker] Compilation failed:

[Webpacker] Compiling…
[Webpacker] Compilation failed:

[Webpacker] Compiling…
[Webpacker] Compilation failed:

I have to run bundle exec bin/webpack-dev-server to get the output I posted above.
I can't post those components but what I'm doing is essentially:

// sidebar_section.tsx

interface Props {
  title: string,
};
const SidebarSection: React.FC<Props> = ({ title }) => (
...
)

and in products_sidebar.tsx I'm just writing some code that won't pass the typescript validation:

<SidebarSection title={false} />

Hey @akoskm,

As of #2224 rails server will now provide the typescript errors in the terminal, although they do need additional formatting as the output is quite verbose. I will put together a PR that cleans this output up.

The nicer error messaging you are getting from ./node_modules/.bin/tsc --jsx react -w --allowSyntheticDefaultImports --noEmit comes from the --pretty setting in Typescript that is on by default through Typescript but unfortunately doesn't show up through webpack.

That being said, you can always do your own error prettying by creating an errorFormatter option in your typescript.js through ts-loader. Take a look at the ts-loader docs for more info

@ShootPassSlam this doesn't solve the problem when no error is shown only the compilation fails with rails server:

[Webpacker] Compiling…
[Webpacker] Compilation failed:

Check this output:

bash-3.2$ rm -rf node_modules && rm -rf public/packs
bash-3.2$ NODE_ENV=production bundle exec rails assets:precompile
W, [2019-09-24T12:43:00.092917 #80001]  WARN -- Skylight: [SKYLIGHT] [4.0.1] Running Skylight in development mode. No data will be reported until you deploy your app.
(To disable this message for all local apps, run `skylight disable_dev_warning`.)
yarn install v1.17.3
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
[3/5] 🚚  Fetching packages...
[4/5] 🔗  Linking dependencies...
warning " > [email protected]" has unmet peer dependency "[email protected] || 0.20.x || 0.22.x || ^1.0.0-0".
[5/5] 🔨  Building fresh packages...
✨  Done in 8.26s.
Compiling…
Compilation failed:

bash-3.2$ make ts-check
npx tsc --jsx react --allowSyntheticDefaultImports --noEmit
app/javascript/packs/components/sidebar/header/header_image.tsx:17:18 - error TS2339: Property 'finally' does not exist on type 'Promise<void>'.

17     img.decode().finally(() => setIsLoading(false));
                    ~~~~~~~


Found 1 error.

make: *** [ts-check] Error 1

@akoskm I am able to see errors after Compilation failed: due to the latest update from #2224

Can you provide your lib/webpacker/compiler.rb file from your webpacker gem?
My run_wepback method provides the errors after Compilation failed:, specifically these lines:

non_empty_streams = [stdout, stderr].delete_if(&:empty?) logger.error "Compilation failed:\n#{non_empty_streams.join("\n\n")}"

Let me know what you have. Thanks!

So if you look at the line 71 of your compiler.rb you have this:

logger.error "Compilation failed:\n#{stderr}"

stderr doesn't actually provide the error output from typescript, so in the most recent version of compiler.rb these lines were changed to:

non_empty_streams = [stdout, stderr].delete_if(&:empty?) logger.error "Compilation failed:\n#{non_empty_streams.join("\n\n")}"

Which now provides the error output from typescript (actually coming from stdout, not stderr).

So if you update your compiler.rb or get the latest version of webpacker, you should start seeing the error output after Compilation failed:

Thanks @ShootPassSlam , hope it's just a version mismatch. gem tells me I'm using 4.0.7:

$ gem info webpacker

*** LOCAL GEMS ***

webpacker (4.0.7)
    Authors: David Heinemeier Hansson, Gaurav Tiwari
    Homepage: https://github.com/rails/webpacker
    License: MIT
    Installed at: /Users/akoskm/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0

    Use webpack to manage app-like JavaScript modules in Rails

and Gemfile.lock has this:

webpacker (4.0.7)
      activesupport (>= 4.2)
      rack-proxy (>= 0.6.1)
      railties (>= 4.2)

I'm not really into ruby things so if could tell me where should for the correct version I would appreciate it.

Since the updates to the gem aren't a new version of the gem, you can target the most up to date version of the gem directly from github in your Gemfile like this:

change this:
gem 'webpacker', '~> 4.0'
to this:
gem 'webpacker', :git => 'https://github.com/rails/webpacker', :branch => 'master'

and run bundle again. This should get you the version of compile.rb with the right error outputs.

Thanks, we'll try this! Do you plan to make a new release with this fix?

Not sure! @jakeNiemiec probably knows this.

Gaurav handles the if and when of all of the releases. I would use what @ShootPassSlam posted above.

@akoskm can we close this issue? Thanks!

@ShootPassSlam yes, I'm using what you proposed as a temporary solution while hoping for a release which contains the fix. 🤞

Was this page helpful?
0 / 5 - 0 ratings