couds / react-bulma-components

React components for Bulma framework
MIT License
1.21k stars 126 forks source link

v4.0 #262

Closed kennethnym closed 3 years ago

kennethnym commented 4 years ago

This is an issue tracking this library's upgrade to v4.0.

New features:

Housekeeping:

cc @couds

edit: marked breaking changes.

kennethnym commented 4 years ago

@couds Bulma 0.9.0 contains some breaking changes, so we have to do a v4 release on this. Maybe push #258 to v5?

kennethnym commented 4 years ago

For TypeScript support, I am currently stuck on supporting advanced imports. It seems like to only way to support advanced imports is to manually re-export all component types under their corresponding advanced import path.

kennethnym commented 4 years ago

Other than that, type definintions should be largely complete.

couds commented 4 years ago

@MrCreeper1008 in which branch are the typescript definitions? I have an idea to fix the import that want to check

kennethnym commented 4 years ago

It's on ts-defs

kennethnym commented 4 years ago

I think we should come up with a better way of importing components, because imo current way of doing it is a bit cluncky. Maybe we should consider supporting tree-shaking?

kennethnym commented 4 years ago

@couds we should also probably rewrite all class components with react hooks, since react recommends hooks over classes.

couds commented 4 years ago

Hi @MrCreeper1008 I think we can do it but that is not a breaking change so we can do it later (v4.1 for example) so let out it as optional for the 4.0.

verheyenkoen commented 4 years ago

@MrCreeper1008 @couds Maybe create a dedicated branch for that? Or can we just send pull requests on a per component basis?

kennethnym commented 4 years ago

Typedefs for compoentns are finished. We're just considering changing how components are imported, so we're holding this off until that is settled

alexpchin commented 4 years ago

Hi, loving the work! Just wondering whether you have an ETA for this update? It seems almost there?

kennethnym commented 4 years ago

yea it is almost there. waiting @couds to rewrite imports.

couds commented 4 years ago

Hi @MrCreeper1008 Thanks a lot for all the work you are doing. This couple a week had been crazy for me. (Changing job and finishing a lot of stuff), I think I will have finally time after Sep 15. I will try my best to do it the weekend of that week. T_T

kennethnym commented 4 years ago

if you want i can finish the rest so you can focus on your stuff.

timorthi commented 4 years ago

Hi, love the library and 4.0 looks to be a great update. Is there anything we can do to help push the project closer to a 4.0 release? :smile:

kennethnym commented 4 years ago

The only big thing left to do is closing #276, so it would be great if you could help with that.

kennethnym commented 4 years ago

Also would be great if you could help improve the documentation.

kennethnym commented 4 years ago

I should be able to finish v4 this week, but it will be released definitely by next week. Sorry for the delays. There are too much stuff going on right now.

Update: all changes are implemented! still deciding whether to rewrite class components. @couds

davepwsmith commented 4 years ago

I am using #next in a hobby application - have noticed that a few of the type exports are missing from index.d.ts, namely:

export {Menu} from './components/menu';
export {Tag} from './components/tab';
export {Tile} from './components/tile';

Not sure if this is overlooked, or intentional, but thought better to point it out :)

D

kennethnym commented 4 years ago

oh shoot you're right. will fix. thanks for the heads up!

fgs-dbudwin commented 3 years ago

I'm playing with v4, and it seems to be working. My big issue is that my bundle size didn't change a whole lot. I was hoping v4 would be significant savings to my bundle size since this package is my single largest dependency...maybe I'm doing something wrong?

This is also in reference to https://github.com/couds/react-bulma-components/issues/276

V3 bundle size: 376.44 KB V4 bundle size: 350.44 KB

I am using Webpack 5 FWIW.

fgs-dbudwin commented 3 years ago

Some more details, here is the view from part of using bundle analyzer...

image

What's interesting to me is I see some modules I'm not using like navbar, tile and media as some examples.

floric commented 3 years ago

@fgs-dbudwin How did you define the imports (avoiding any default imports)? And: did you activate Treeshaking properly using the sideeffects-property and verified that Treeshaking works for other libs?

kennethnym commented 3 years ago

@fgs-dbudwin in v4 you import components like such:

import { Columns, Button } from 'react-bulma-components'

This will allow tree shaking to work properly. Let me know if you still have issues!

fgs-dbudwin commented 3 years ago

@floric @MrCreeper1008

Yes, I have structured my imports like suggested. I have also had a lot of luck lately getting tree shaking to reduce my bundle size using Webpack 5 so I trust that it works for other libs (like moment and @fortawesome/react-fontawesome for example). I have made a minimally reproduceable example of tree shaking not seeming to work for my use case which can be accessed here: https://github.com/fgs-dbudwin/react-bulma-components-v4-tree-shaking

Given that repo, clone it and then do:

  1. npm install
  2. npm run build
  3. Access http://127.0.0.1:8888/ in your browser.
    1. In the menu that expands from the left, be sure to select "Stat" under "Treemap sizes" and check "Show content of concatenated modules"

You should see something like this:

image

This is a surprising result since in index.tsx I am only including import { Container, Heading, Hero } from "react-bulma-components"; but yet my bundle contains all sorts of other unused modules from react-bulma-components.

floric commented 3 years ago

Hey :) Thanks for the clean example repository. Thats the way issues should be reported! :+1:

I can reproduce your point and it's most likely caused by an invalid Typescript configuration.

Try a ES module type like es6 instead of CommonJS (otherwise Treeshaking won't work):

  "compilerOptions": {
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "es6",
    "target": "es2019",
    "jsx": "react",
    "esModuleInterop": true,
    "allowJs": true,
    "inlineSources": true,
    "sourceRoot": "/"
  }
}

At least this worked in my short test and reduced the bundle size to 149kb :)

bundle

fgs-dbudwin commented 3 years ago

@floric good catch, that does address the issue in my sample. That change leads to 400+ errors in my actual code though 😲

I am getting some warnings related to react-bulma-components now...I think it's similar to this comment from above about missing types.

The warnings look like:

export 'Field' (imported as 'Field') was not found in 'react-bulma-components' (possible exports: Box, Breadcrumb, Button, Card, Columns, Container, Content, Dropdown, Element, Footer, Form, Heading, Hero, Icon, Image, Level, Loader, Media, Menu, Message, Modal, Navbar, Notification, Pagination, Panel, Progress, Section, Table, Tabs, Tag, Tile)

In addition to Field, it also warns about Control, Label, Input, Help, Textarea, Select.

fgs-dbudwin commented 3 years ago

FWIW, since other people may stumble across this--switching from "CommonJS" to "es6" is seemingly causing other issues about module resolution even though react-bulma-components items are resolving correctly. I'm not advanced enough with JS to understand why this is happening. I added a new commit to my previous example that demonstrates this: https://github.com/fgs-dbudwin/react-bulma-components-v4-tree-shaking/commit/861c4c90de9f2796baf7d7d85fae1b30ef5cfdd3

For instance, line 1 of index.tsx is throwing an error that says: Cannot find module '@fortawesome/fontawesome-svg-core'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?ts(2792)

This isn't a problem of react-bulma-components, but I'd like to use tree shaking and continue to help test v4, but can't seem to understand why my imports are now broken.

jamwaffles commented 3 years ago

In addition to Field, it also warns about Control, Label, Input, Help, Textarea, Select.

I haven't been keeping too close an eye on RBC 4.0, but aren't these under Form, i.e.

import { Form } from 'react-bulma-components';

<Form.Control>
    <Form.Input>
</Form.Control>

I think setting moduleResolution to node as suggested will fix your import issues as well - it tells the TS compiler to go looking in node_modules as Node itself would.

fgs-dbudwin commented 3 years ago

@jamwaffles I used to have my imports for Form related objects structured that way, but changed them due to this comment: https://github.com/couds/react-bulma-components/issues/276#issuecomment-668418146

But now that I re-read that comment, it looks like @couds was proposing that new format which didn't get implemented--so I may need to revert that change.

fgs-dbudwin commented 3 years ago

Good news, switching from "CommonJS" to "es6" (or later) AND adding "moduleResolution": "node" to my tsconfig.json fixed the issue I was seeing yesterday; however, my Jest test don't seem to work anymore. This isn't related to the aforementioned change--I get the same error regardless. I have added a commit to my example repo to reporduce this...just run npm run test: https://github.com/fgs-dbudwin/react-bulma-components-v4-tree-shaking/commit/e6252dc6b344b1ec1d2c34a86d25f793acf1000f

jest

 FAIL  frontend/src/__test__/hello-world.test.tsx
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /dev/react-bulma-components-v4-tree-shaking/node_modules/react-bulma-components/lib/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import * as Form from './components/form';
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      3 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
      4 | import React from "react";
    > 5 | import { Container, Heading, Hero } from "react-bulma-components";
        | ^
      6 |
      7 | export default function HelloWorld(): React.ReactElement<object> {
      8 |     return (

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (frontend/src/hello-world.tsx:5:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        4.101 s
Ran all test suites.
floric commented 3 years ago

@fgs-dbudwin Ah, right. The moduleResolution was missing :(

The problem is most likely, that Jest doesn't support ES Modules yet (which are now the result from Typescript after the change). See this issue for more information: https://github.com/facebook/jest/issues/4842 They are working on it though right now: https://github.com/facebook/jest/issues/9430

In the meantime you can try to use babel-jest instead together with Babel to transform the TS to compliant JS.

fgs-dbudwin commented 3 years ago

@floric unfortunately, that still fails when switching ts-jest for babel-jest. The tests work just fine in v3.4 of react-bulma-components, but not on the v4.0 branch. My attempt at using babel-jest can been seen on my latest commit: https://github.com/fgs-dbudwin/react-bulma-components-v4-tree-shaking/commit/f181f2abca09c3b0387f13943e2209ac9bc19f4f

I'm not otherwise using Babel, so I'm not surprised this didn't work. The new error I get:

jest

 FAIL  frontend/src/__test__/hello-world.test.tsx
  ● Test suite failed to run

    SyntaxError: /dev/react-bulma-components-v4-tree-shaking/frontend/src/__test__/hello-world.test.tsx: Support for the experimental syntax 'jsx' isn't currently enabled (9:12):

       7 |
       8 | it("shows 'Hello World!'", () => {
    >  9 |     render(<HelloWorld />);
         |            ^
      10 |
      11 |     expect(screen.getByText("Hello World!")).toBeInTheDocument();
      12 | });

    Add @babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.
    If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://git.io/vb4yA) to the 'plugins' section to enable parsing.

      at Parser._raise (node_modules/@babel/parser/src/parser/error.js:60:45)
      at Parser.raiseWithData (node_modules/@babel/parser/src/parser/error.js:55:17)
      at Parser.expectOnePlugin (node_modules/@babel/parser/src/parser/util.js:157:18)
      at Parser.parseExprAtom (node_modules/@babel/parser/src/parser/expression.js:1180:18)
      at Parser.parseExprSubscripts (node_modules/@babel/parser/src/parser/expression.js:563:23)
      at Parser.parseUpdate (node_modules/@babel/parser/src/parser/expression.js:543:21)
      at Parser.parseMaybeUnary (node_modules/@babel/parser/src/parser/expression.js:527:17)
      at Parser.parseExprOps (node_modules/@babel/parser/src/parser/expression.js:343:23)
      at Parser.parseMaybeConditional (node_modules/@babel/parser/src/parser/expression.js:308:23)
      at Parser.parseMaybeAssign (node_modules/@babel/parser/src/parser/expression.js:263:21)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.197 **s**
fgs-dbudwin commented 3 years ago

I got the tests to pass! Two things were needed in jest.config.js:

  1. preset: "ts-jest/presets/js-with-ts",
  2. transformIgnorePatterns: ["<rootDir>/node_modules/react-bulma-componets/"],

The tests are initially slower to run than expected so I will keep tinkering. The initial run took 60s, subsequent runs take 1.5s.

From Jest's documentation:

Sometimes it happens (especially in React Native or TypeScript projects) that 3rd party modules are published as untranspiled. Since all files inside node_modules are not transformed by default, Jest will not understand the code in these modules, resulting in syntax errors. To overcome this, you may use transformIgnorePatterns to allow transpiling such modules. You'll find a good example of this use case in React Native Guide.

Is that the case here? I thought a big push of v4 was to make it more TS friendly? Is it simply because the dev branch isn't transpiled?

kennethnym commented 3 years ago

@fgs-dbudwin this is weird. I configured babel so that it will transpire import statements in test environment:

['@babel/preset-env', { modules: isTestEnv ? 'commonjs' : false }]

according to the jest documentation: https://jestjs.io/docs/en/getting-started#using-babel. In normal environment import statements in src/index.js are not transpired to enable tree shaking, which seems to be working just fine.

fgs-dbudwin commented 3 years ago

@MrCreeper1008 are you able to reproduce my issue? After I got the single test to work in my sample code, I ported the change over to my production code which has about 500 Jest tests. It took one hour before exiting (normally completes in one minute) and none of the tests passed because I was getting out of memory errors for my Jest process. So, unfortunately, my tweak above isn't a real solution. I'm open to trying other things or helping as I can. I'm not familiar with babel--we don't use it in our project--so I can't provide much feedback with regard to that tool.

kennethnym commented 3 years ago

I'll try to set up a new project using v4 and see how it goes.

kennethnym commented 3 years ago

@fgs-dbudwin in v4 import statements are not compiled to enable tree shaking, which is why you'll encounter syntax errors in jest since it doesn't support import/export statements. You need to tell jest to compile them specifically for this library:

"transformIgnorePatterns": ["/node_modules/(?!react-bulma-components).+\\.js$"]

I'll add this in the new documentation. I also fixed incorrect TypeScript definition paths, so autocompletion with TypeScript should be working now.

fgs-dbudwin commented 3 years ago

@MrCreeper1008, unfortunately, pulling the latest version of the @next branch and using transformIgnorePatterns like you suggested still results in the same error I originally got: https://github.com/couds/react-bulma-components/issues/262#issuecomment-725555286

I updated my example repo to match your suggestion: https://github.com/fgs-dbudwin/react-bulma-components-v4-tree-shaking

kennethnym commented 3 years ago

This is weird, I created a create-react-app in TypeScript and got a syntax error about the import statements. I added the transformIgnorePattern and the error went away. I guess I'll have to look deeper.

fgs-dbudwin commented 3 years ago

I'm not using create-react-app for whatever difference it may have made.

kennethnym commented 3 years ago

Turns out the memory issue is an issue on ts-jest: https://github.com/kulshekhar/ts-jest/issues/1967. Basically, compiled modules are cached redundantly.

fgs-dbudwin commented 3 years ago

Reading that issue, it looks like the underlying issue may be with Jest itself--the issue was crossposted here: https://github.com/facebook/jest/issues/10550

Not much activity on it. I take it that you're not using ts-jest which is why you're not seeing the same issues I am.

kennethnym commented 3 years ago

My guess is that the issue only happens in large projects with many test cases. A solution is for us to ship a commonjs version of our code that you can import in tests (like react-bulma-components/lib/index.cjs) but I am reluctant to do so because I reckon very few people will use it and it's not worth the extra installation time. @couds thoughts?

fgs-dbudwin commented 3 years ago

Can you explain to me what changed between v3 and v4 to expose this issue?

kennethnym commented 3 years ago

in v3 import statements are transpiled but in v4 they aren't anymore to enable tree shaking.

kennethnym commented 3 years ago

Marked breaking changes.

kennethnym commented 3 years ago

Some missing features are added when I am writing the new documentation. Decided to also perform some housekeeping tasks in v4 to tidy up the code base.

couds commented 3 years ago

Hi @all I took a while but finally we have a release candidate for V4. You can try it installing the next tag npm i react-bulma-components@next

If not big issues are found I will release it next week

Thanks for the patience!

davepwsmith commented 3 years ago

@couds I have been using the v4 branches for a while, and this seems to break quite a lot that was previously working in terms of types in particular, but also functionally - is there an easy way to see what has changed, or view the docs so that I can work out how to update these?

One thing in particular that I think will need updating is the types on renderAs - I am using Gatsby, and it won't let me use a gatsbyLink as renderAs, which is pretty crucial e.g. for navigation. (https://github.com/couds/react-bulma-components/issues/314#issue-855096086)

I'm going to take a look and see if there is anything I can do about it, but thought I would let you know early!