GithubHelp home page GithubHelp logo

Comments (13)

Rich-Harris avatar Rich-Harris commented on May 29, 2024 1

Okay, I've done some digging. It looks like this is one of this incredibly frustrating interop headaches caused by back-and-forth conversion between CommonJS and ES modules. Specifically, it looks like the add-module-exports Babel plugin is causing havoc, because it violates the expectation in rollup-plugin-commonjs that a module with __esModule: true will have exports.default rather than module.exports.

The good news is that it's easy to fix – just use the dist file rather than bundling the library yourself:

import styled from 'styled-components/dist/styled-components.js'

Or, use the existing import but update your Rollup config:

import { resolve } from 'path'
const styledComponentsDist = resolve(__dirname, 'node_modules/styled-components/dist/styled-components.js')

export default {
  entry: 'src/main.js',
  dest: 'dist/bundle.js',
  preferConst: true,
  plugins: [
    {
      resolveId (importee) {
        if (importee === 'styled-components') return styledComponentsDist;
      }
    },
    replace({
      'process.env.NODE_ENV': JSON.stringify('development')
    }),
    ...

Slightly off-topic, but as part of my digging I experimented with building this library with Rollup rather than Webpack (so that it could export an ES module bundle for the benefit of people using Webpack 2 or Rollup like @nicolasparada). The UMD build is 13% smaller (20,549 bytes gzipped down from 23,553) and parses roughly 60% quicker (~8ms in Chrome down from ~20ms, similar increase in Safari, less in Firefox). Any interest in a PR? Totally cool if not but the offer's there 😀

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024 1

Thanks to the amazing @Rich-Harris, we're now bundling with Rollup which not only means a reduction of size for the UMD bundle, but also a .es.js bundle that will fix this issue!

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024

This very much sounds like it's not an issue with styled-components but with rollup-plugin-commonjs@Rich-Harris might have some input here?

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024

Yes yes yes please submit a PR!!

The only reason I used webpack was because I already knew how to configure it and had to get it done, I've been meaning to look into rollup, so this would be a very appreciated PR!

EDIT: Would that fix this issue as well?

from styled-components.

Rich-Harris avatar Rich-Harris commented on May 29, 2024

Great! Will send it later this am.

Would that fix this issue as well?

Yes, by adding module (aka jsnext:main) in package.json, Rollup and Webpack 2 would locate dist/styled-components.es.js (or whatever the filename is) and it would be treated as a native ES module, no monkeying around with rollup-plugin-commonjs necessary. Faster builds for those library consumers too.

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024

Yes, by adding module (aka jsnext:main) in package.json, Rollup and Webpack 2 would locate dist/styled-components.es.js (or whatever the filename is) and it would be treated as a native ES module, no monkeying around with rollup-plugin-commonjs necessary. Faster builds for those library consumers too.

Hmm, I've been bitten a few times by jsnext:main with people sending over code with stage-0 features. How would we mitigate that? Does rollup have a "transpile-to-es2016" mode?

from styled-components.

Rich-Harris avatar Rich-Harris commented on May 29, 2024

jsnext:main is purely about how the module is exposed – whereas Node, or Browserify or Webpack will look for the main field (and fall back to index.js), expecting to find a file with a module.exports = ... or exports.foo = ..., Rollup and Webpack 2 will first look for module or jsnext:main, expecting to find a file with export declarations.

The actual code, other than the means of export, is identical in both cases – in other words everything gets transpiled with the same Babel config (bar import and export stuff). It's a community convention rather than anything 'official' (insofar as anything in package.json is official), but tons of major libraries (D3, Lodash, PouchDB, etc etc) are already using it as it allows for smaller builds and (where applicable) tree-shaking.

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024

jsnext:main is purely about how the module is exposed

Ohh, alright, that sounds very good to me. Thanks for clearing that up! (is there a canonical source for this? I've argued about this with people before)

from styled-components.

nicolasparada avatar nicolasparada commented on May 29, 2024

Nice.

from styled-components.

Rich-Harris avatar Rich-Harris commented on May 29, 2024

is there a canonical source for this?

Ha! Well, I wrote https://github.com/rollup/rollup/wiki/jsnext:main to explain what is was, and that's sort of become a canonical source. The name jsnext (not my invention!) is confusing as it suggests that anything goes, but using it to point to source code that contains non-ES5 (particularly stage 0-3) features has caused thousands of hours of unnecessary frustration and confusion, so I've always argued that library authors should ship code that runs in their target environments (import and export being the exception because there is no ES5 equivalent – module.exports is just as fictional outside Node, the only difference being that import and export won't be fictional for very long).

from styled-components.

mxstbr avatar mxstbr commented on May 29, 2024

Interest, thanks for clearing all of that up! Looking forward to the PR 👍

from styled-components.

nicolasparada avatar nicolasparada commented on May 29, 2024

The .es.js file has some require statements... Using the same code of the repo from before, those require end up in my bundled file...

from styled-components.

Rich-Harris avatar Rich-Harris commented on May 29, 2024

Well, this is embarrassing! I'm at a loss as to how I didn't notice this in my testing yesterday...

It looks like the files in question are vendor/postcss/container.js and vendor/postcss/root.js, which have both import declarations and require statements. The reason for that is that those modules have a cyclical dependency on each other, and nesting the require statement is a way to evaluate things lazily.

It is possible to order the import declarations in such a way that the cyclical dependency isn't a problem (i.e. such that container.js is included before root.js, since class Root extends Container). It's a bit counter-intuitive, but as far as I can tell it does work. Working on a PR as we speak.

(Just to clarify: this isn't a Rollup issue per se, but a fundamental constraint of ES modules in that they can't be evaluated lazily like CommonJS – one of the necessary trade-offs for their benefits, unfortunately.)

So sorry about the mess!

from styled-components.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.