linaria icon indicating copy to clipboard operation
linaria copied to clipboard

1.4.x beta: buildOptions() conflicts with required options for Typescript project

Open justjake opened this issue 4 years ago • 7 comments

Environment

  • Linaria version: 1.4.0-beta.9
  • Bundler (+ version): Webpack 4.41.5
  • Node.js version: v10.15.3
  • OS: macOS 10.14.6 (18G103)

Description

The buildOptions function always specifies babel plugin @babel/plugin-transform-modules-commonjs with no options (defaulting to noInterop: false) but my project must be built with ['@babel/plugin-transform-modules-commonjs', { noInterop: true }].

https://github.com/callstack/linaria/blob/df7cd179e190936c9113dabcb67358432832d03e/src/babel/evaluators/buildOptions.ts#L18-L22

My project is a large Typescript codebase that does not use --esModuleInterop. That means that in our source files, the import syntax for a commonjs module with a single export is import * as singleExport from 'module-name'. When our code is pre-processed with @babel/plugin-transform-modules-commonjs, the result of the import statement is now some unexpected value.

Concrete example

// node_modules/chroma-js/index.js
function chroma(args) { /* ... */ }
chroma.something = 1
chroma.otherThing = 2
module.exports = chroma
// src/client/components/MyComponent.tsx
import * as chroma from 'chroma-js'
import { css } from 'linaria'

// During Linaria's evaluation step, this expression will throw an error because
// "chroma is not a function." because @babel/plugin-transform-modules-commonjs
// gives different results for the `import *` above.
const color = chroma('red').lighten(0.5).css()

const className = css`
  color: ${color};
`

Reproducible Demo

https://github.com/justjake/linaria-babel-options-issue-repro

justjake avatar May 17 '20 17:05 justjake

Related: there's a similar issue with shaker because it unshifts a "@babel/preset-env" even when the user may already have @babel/preset-env configured.

justjake avatar May 17 '20 18:05 justjake

Hi 😉 Could you provide a link to a repository where we will able to reproduce this bug ? Thanks in advance!

TMaszko avatar May 18 '20 10:05 TMaszko

@TMaszko thanks for the quick response. I'll try to provide a repo some time this week. In the mean time, I started working on a PR to address the issue that I'll submit in a few minutes that gives more color to this.

justjake avatar May 18 '20 18:05 justjake

@TMaszko proposed fix: https://github.com/callstack/linaria/pull/613

justjake avatar May 18 '20 18:05 justjake

@TMaszko Here is a reproduction: https://github.com/justjake/linaria-babel-options-issue-repro

justjake avatar May 23 '20 19:05 justjake

I'm getting build options conflicts in 2.0-rc0

console output
ERROR in ./src/components/SiteHeader.tsx
Module build failed (from ./node_modules/linaria/loader.js):
Error: ~project/src/components/SiteHeader.tsx: An unexpected runtime error ocurred during dependencies evaluation:
Error: Duplicate plugin/preset detected.
If you'd like to use two separate instances of a plugin,
they need separate names, e.g.

  plugins: [
    ['some-plugin', {}],
    ['some-plugin', {}, 'some unique name'],
  ]

Duplicates detected are:
[
  {
    "alias": "~project/node_modules/@babel/plugin-transform-runtime/lib/index.js",
    "options": {
      "useESModules": false
    },
    "dirname": "~project",
    "ownPass": false,
    "file": {
      "request": "@babel/plugin-transform-runtime",
      "resolved": "~project/node_modules/@babel/plugin-transform-runtime/lib/index.js"
    }
  },
  {
    "alias": "~project/node_modules/@babel/plugin-transform-runtime/lib/index.js",
    "dirname": "~project",
    "ownPass": false,
    "file": {
      "request": "@babel/plugin-transform-runtime",
      "resolved": "~project/node_modules/@babel/plugin-transform-runtime/lib/index.js"
    }
  }
]
    at assertNoDuplicates (~project/node_modules/@babel/core/lib/config/config-descriptors.js:206:13)
    at createDescriptors (~project/node_modules/@babel/core/lib/config/config-descriptors.js:114:3)
    at createPluginDescriptors (~project/node_modules/@babel/core/lib/config/config-descriptors.js:105:10)
    at ~project/node_modules/@babel/core/lib/config/config-descriptors.js:63:53
    at cachedFunction (~project/node_modules/@babel/core/lib/config/caching.js:62:27)
    at cachedFunction.next (<anonymous>)
    at evaluateSync (~project/node_modules/gensync/index.js:244:28)
    at sync (~project/node_modules/gensync/index.js:84:14)
    at plugins (~project/node_modules/@babel/core/lib/config/config-descriptors.js:28:77)
    at mergeChainOpts (~project/node_modules/@babel/core/lib/config/config-chain.js:318:26)
    at ~project/node_modules/@babel/core/lib/config/config-chain.js:282:7
    at Generator.next (<anonymous>)
    at buildRootChain (~project/node_modules/@babel/core/lib/config/config-chain.js:67:36)
    at buildRootChain.next (<anonymous>)
    at loadPrivatePartialConfig (~project/node_modules/@babel/core/lib/config/partial.js:95:62)
    at loadPrivatePartialConfig.next (<anonymous>)

It may happen when your code or third party module is invalid or uses identifiers not available in Node environment, eg. window.
Note that line numbers in above stack trace will most likely not match, because Linaria needed to transform your code a bit.

    at PluginPass.enter (~project/node_modules/linaria/src/babel/extract.ts:172:21)
    at newFn (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/visitors.js:179:21)
    at NodePath._call (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:55:20)
    at NodePath.call (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:42:17)
    at NodePath.visit (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/path/context.js:90:31)
    at TraversalContext.visitQueue (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:112:16)
    at TraversalContext.visitSingle (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:84:19)
    at TraversalContext.visit (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/context.js:140:19)
    at Function.traverse.node (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/index.js:84:17)
    at traverse (~project/node_modules/@babel/core/node_modules/@babel/traverse/lib/index.js:66:12)
    at transformFile (~project/node_modules/@babel/core/lib/transformation/index.js:107:29)
    at transformFile.next (<anonymous>)
    at run (~project/node_modules/@babel/core/lib/transformation/index.js:35:12)
    at run.next (<anonymous>)
    at Object.<anonymous> (~project/node_modules/@babel/core/lib/transform-ast.js:28:41)
    at Generator.next (<anonymous>)
 @ ./app/j/containers/SiteHeaderContainer.ts 3:0-54 42:3-13
 @ ./src/header.entry.tsx

Here's my Babel presets config:

  '@babel/preset-env',
  '@babel/preset-typescript',
  '@babel/preset-react',
  'linaria/babel',

turadg avatar Aug 11 '20 00:08 turadg

I tried again in 2.0.0-rc.1 and I'm not getting them anymore. I also updated the babelOptions to linaria/loader to have the bar essentials,

          use: [
            babelLoader,
            {
              loader: 'linaria/loader',
              options: {
                sourceMap,
                babelOptions: {
                  presets: [
                    '@babel/preset-typescript',
                    '@babel/preset-react',
                    'linaria/babel',
                  ],
                },
              },
            },

turadg avatar Aug 26 '20 01:08 turadg

This issue is extremely old, while it has a repro - all versions in it are outdated and it's hard to make the whole thing working. If it's still a problem, please open a new issue and provide reproduction. Thanks.

layershifter avatar Oct 13 '23 19:10 layershifter