Home > Software design >  NextJS webpack config - Exclude files from being compiled
NextJS webpack config - Exclude files from being compiled

Time:03-04

I need some help with NextJS webpack config?

I have a mono-repo and share code between React-Native and NextJS. To split OS-specific code I separated the native and the web code like that: (Login.web.tsx & Login.native.tsx)

Example: /Login/index.tsx

import React, { lazy, ReactElement, Suspense } from 'react'
import { Platform, View } from 'react-native'

const LoginComponent = lazy(() => (Platform.OS === 'web' ? import('./Login.web') : import('./Login.native')))

const Login = (props: NavigationProp): ReactElement => {
  return (
    <Suspense fallback={<View />}>
      <LoginComponent {...props} />
    </Suspense>
  )
}

export default Login

This example code is located in the ui-screens project and will be imported into the one and only NextJS page like that

import { Login } from '@monorepo/ui-screens'

export default function App() {
  return (
    <Login />
  )
}

React-Native deals perfectly with that and loads the correct Login.native.tsx page. But the NextJS webpack compiler still sees this file Login.native.tsx and tries to compile it, which obviously causes errors.

When I change the code of /Login/index.tsx like that, for test purposes, my web app runs fine

const LoginComponent = lazy(() => (Platform.OS === 'web' ? import('./Login.web') : import('./Login.web')))

How can I make webpack to exclude files that have the *.native.* extensions?

Note: I tried RemovePlugin:

const withPlugins = require('next-compose-plugins')
const withTM = require('next-transpile-modules')([
  'react-native',
  '@types/react-native',
  '@monorepo/ui-screens'
])
const RemovePlugin = require('remove-files-webpack-plugin')

module.exports = withPlugins([withTM()], {
  enableSvg: true,
  esModule: true,
  images: {
    disableStaticImages: true
  },
  plugins: [
    new RemovePlugin({
      before: {
        include: ['Login.native.tsx']
      }
    })
  ],
  webpack: (config) => {
    config.resolve.alias = {
      ...(config.resolve.alias || {}),
     'react-native$': 'react-native-web',
    }
    config.resolve.extensions = ['.web.js', '.web.jsx', '.web.ts', ...config.resolve.extensions]
    return config
  }
}

But it has no effect.

Any help would be much appreciated.

CodePudding user response:

After hours of reading the webpack docs, Github issues and comments, I have finally found a super easy solution called webpackIgnore

Just by inserting it into the import command, I can tell webpack to literally ignore the file at compilation time:

const LoginComponent = lazy(
 () => (Platform.OS === 'web' ? 
 import('./Login.web'): 
 import(/* webpackIgnore: true */ './Login.native'))
)

I love this elegant solution.

Now I only have to tell my Typescript compiler to NOT delete this line.

  • Related