pugjs / babel-plugin-transform-react-pug

A plugin for transpiling pug templates to jsx
MIT License
811 stars 47 forks source link

Pug tag disrespects module definition? #55

Closed stevefan1999-personal closed 6 years ago

stevefan1999-personal commented 6 years ago

It seems like Pug transpile its tags directly into React.createElement(Foo, ...)-ish function instead of <Foo>...</Foo>, that eventually compiles to React.createElement(_foo, ...) (but not the full name Foo, instead interoped and resolved), and it breaks references to imported files (ReferenceError). I don't know why would this happen. Is anyone having the same issue?

ezhlobo commented 6 years ago

@stevefan1999 this plugin transpiles pug into jsx. So Foo ... will be <Foo>...</Foo>. Then it's usually passed to next plugin transform-react-jsx.

It sounds like the problem in your build-flow but I can't say more. Maybe you can provide more details, for example sharing .babelrc is a good start.

stevefan1999-personal commented 6 years ago

🤔I made a reproducible repo. CC @ezhlobo

stevefan1999-personal commented 6 years ago

🤔Or perhaps there's something wrong with the TypeScript compiler? I changed tsconfig.json to the following:

{
  "compilerOptions": {
    "jsx": "preserve",
    "module": "es2015",
    "moduleResolution": "node",
    "target": "es2018"
  },
  "exclude": ["node_modules"]
}

Then I ran tsc, but App.tsx is generating App.jsx with the following content:

import * as React from 'react';
import { render } from 'react-dom';
const App = () => pug `
  Foo/
`;
render(<App />, document.getElementById('root'));

EDIT: Yep, pretty sure this is a victim of module elision in TS.

ezhlobo commented 6 years ago

@stevefan1999 thanks for the repo. I'll be able to check that today later but it significantly simplifies everything for me ;).

stevefan1999-personal commented 6 years ago

Workaround:

  1. Change module to es2015 or better in tsconfig.json so that the actual module resolve strategy is handled by Babel or other tools
  2. Either put a comma-list expression or a dummy expression after the import
    import Foo from './Foo'
    import Bar from './Bar'
    Foo, Bar

    Or

    import Foo from './Foo'; Foo
    import Bar from './Bar'; Bar

    But both of them are ugly workarounds.

Reference: https://github.com/Microsoft/TypeScript/wiki/FAQ#why-are-imports-being-elided-in-my-emit

This is a reanimation of https://github.com/Microsoft/TypeScript/issues/18586 as well.