Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage with Next.js v12 and SWC as the compiler #610

Open
rtrembecky opened this issue Nov 26, 2021 · 5 comments
Open

Usage with Next.js v12 and SWC as the compiler #610

rtrembecky opened this issue Nov 26, 2021 · 5 comments

Comments

@rtrembecky
Copy link

Hi, I'd like to ask what is the correct way to use graphql-let with Next.js v12, more specifically with SWC though.

What I've done:

  • I had babel.config.js file at first
  • I ran yarn build - I was told by next.js that SWC is not used because of recognized babel config
  • I removed babel.config.js
  • I changed jest.config.js as suggested here - Add Jest transformer using next-swc vercel/next.js#30811 (comment)
  • I ran yarn build again - This time, no warning from next.js build, so I guess SWC is used.

What I'm worried about:

My current next.config.js looks somewhat like this:

module.exports = {
  i18n,
  pageExtensions: ["page.tsx"],
  webpack(config, options) {
    // taken from: https://github.com/vercel/next.js/blob/canary/examples/with-typescript-graphql/next.config.js
    config.module.rules.push(
      {
        test: /\.graphql$/u,
        exclude: /node_modules/u,
        use: [options.defaultLoaders.babel, { loader: "graphql-let/loader" }],
      },
      {
        test: /\.graphqls$/u,
        exclude: /node_modules/u,
        use: ["graphql-let/schema/loader"],
      },
    )

    return config
  },
}

I see the options.defaultLoaders.babel entry (it is { loader: 'babel-loader', options: { presets: ['@babel/preset-typescript', '@babel/preset-react'] } } entry in the graphql-let docs), and I also believe graphql-let/loader is using babel.

The question is:

Does it mean both SWC and Babel fire up when compiling the code? Does Babel jump in only to take care of .graphqls? files, no it is OK in terms of performance? Is the next step in getting rid of Babel (and towards better performance) for this library to create an SWC-based transformer?

@rtrembecky
Copy link
Author

I'll continue with a related topic, which is the integration with Jest.
I think I figured this one out, so I want to share my Jest config here to help anybody who struggles with it. I'm using the new next/jest package to bootstrap the config, but I still need to override something:

const nextJest = require("next/jest")

const createJestConfig = nextJest({ dir: "." })

// for reference, what's included and how the overrides work:
// https://github.com/vercel/next.js/blob/canary/packages/next/build/jest/jest.ts
const customJestConfig = {
  moduleDirectories: ["node_modules", "src/test"],
  moduleNameMapper: {
    "@/components/(.*)": "<rootDir>/src/components/$1",
    "@/features/(.*)": "<rootDir>/src/features/$1",
    "@/graphql/(.*)": "<rootDir>/src/graphql/$1",
    "@/pages/(.*)": "<rootDir>/src/pages/$1",
    "@/theme/(.*)": "<rootDir>/src/theme/$1",
    "@/utils/(.*)": "<rootDir>/src/utils/$1",
    "@/test/(.*)": "<rootDir>/test/$1",
    "@/toolsSetup/(.*)": "<rootDir>/toolsSetup/$1",
  },
  testEnvironment: "jsdom",
  transform: {
    "^.+\\.graphql$": [
      "graphql-let/jestTransformer",
      { subsequentTransformer: "next/dist/build/swc/jest-transformer" },
    ],
  },
  setupFilesAfterEnv: ["<rootDir>/test/config/setupFiles.ts"],
  // allow SWC to run on typescript code of generated types (to use schema model types)
  //   or cached types (to use enum's code), while still keeping mode_modules disabled
  transformIgnorePatterns: ["node_modules/(?!@types/graphql-let|.cache/graphql-let)"],
  testPathIgnorePatterns: ["<rootDir>/coverage/", "<rootDir>/test/e2e/"],
  collectCoverageFrom: [
    "src/**/*.{js,jsx,ts,tsx}",
    "!**/*.stories.tsx",
    // types (graphql, custom)
    "!**/*.d.ts",
    // example components, not used in production
    "!**/examples/**",
  ],
}

const asyncConfig = createJestConfig(customJestConfig)

module.exports = async () => {
  const config = await asyncConfig()

  // next/jest ignores node_modules and allows to add more ignore patterns, but we need to override them fully to whitelist some node_modules
  // https://github.com/vercel/next.js/blob/canary/packages/next/build/jest/jest.ts
  config.transformIgnorePatterns = customJestConfig.transformIgnorePatterns

  return config
}

For SWC, the important things are:

  • next/jest automatically adds SWC as the compiler for js/ts/jsx/tsx (in transform)
  • in transform:, for .graphql files, the subsequentTransformer needs to be defined to use next's internal SWC Jest transformer

@solomonhawk
Copy link

@rtrembecky Does your setup yield correct coverage reports for .ts* files? I'm seeing incorrect line numbers and coverage %on a similar setup (typescript, next 12.0.7, jest 27.4.5, next/jest) and I have to bail out of the swc transformer injected by next/jest and use babel in order for sourcemaps to work correctly.

e.g. this gives proper coverage reports:

transform: {
    '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
},

@rtrembecky
Copy link
Author

@solomonhawk You're right. I don't check coverage in my project, but I tested it now and it's hugely off indeed.

@tettoffensive
Copy link

@rtrembecky Did you ever get anywhere with this? I'm wanting to use .graphql files instead of gql`` tags in my .ts files. While I'm still locked in to babel (because I'm using emotion), I'd rather not add another thing that won't work with SWC.

@rtrembecky
Copy link
Author

@tettoffensive Hi, I can provide no update on this.

ardelato added a commit to iFixit/react-commerce that referenced this issue Dec 5, 2022
Next.js has added a wrapper around configuring Jest to run tests. This
wrapper will do a lot of things we are already doing in our configuration.

The ones we are more paticularly interested in is the auto-mocking of
`.css` modules and its variants, as well as mocking image imports. This
means we can remove our own file mock and configuration settings. As well
as the default test paths that get ignored.

In addition, `next/jest` uses `SWC` to transform the files which is a
lot faster than Babel and is something we have already implemented in
our monorepo
iFixit/ifixit@37985f3.

Lastly, because of the default settings for Jest that `next/jest` has
we needed to manually override the `transformIgnorePatterns` to use
an empty array and thus whitelist all node_modules paths.

piglovesyou/graphql-let#610 (comment)

All the default configurations can be found here:
https://github.com/vercel/next.js/blob/canary/packages/next/build/jest/jest.ts#L101C12-L179
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants