Skip to content
This repository has been archived by the owner on Jul 6, 2021. It is now read-only.

withCss does not work when importing a css file from node_modules on production build #498

Closed
macrozone opened this issue Jul 21, 2019 · 9 comments

Comments

@macrozone
Copy link

macrozone commented Jul 21, 2019

my config: (custom server)

const app = next({
  conf: withCSS({
    cssLoaderOptions: {
      url: false,
    },
  }),
});

then somewhere in my code:

import "@react-page/plugins-image/lib/index.css";

This seems to work on dev, but when i doing a production build:

../node_modules/@react-page/plugins-image/lib/index.css 45:0
Module parse failed: Unexpected token (45:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|  */
|
> .ory-plugins-content-image {
|   width: 100%;
| }
@macrozone macrozone changed the title withCss does not work when a node_module imports a css file on production build withCss does not work when importing a css file from node_modules on production build Jul 21, 2019
@macrozone
Copy link
Author

macrozone commented Jul 21, 2019

i tried proposed solutions from the dozens of other similar issues:

if (typeof require !== "undefined") {
  // tslint:disable-next-line:no-empty
  require.extensions[".less"] = () => {};
  // tslint:disable-next-line:no-empty
  require.extensions[".css"] = () => {};
}

--> makes no difference

  • adding webpack config to the next-config:
nst app = next({
  dev: !isProduction,
  conf: withCSS({
    cssLoaderOptions: {
      url: false,
    },
    webpack: (config) => {
      config.module.rules.push({
        test: /\.css$/,
        loader: "style-loader!css-loader",
      });
    },
  }),
});

--> makes no difference

@macrozone
Copy link
Author

ok, seems that i still need a next.config.js for this to work in production...

@calvinchankf
Copy link

calvinchankf commented Jul 28, 2019

oh wait. @macrozone so finally it is still unsolved?

@macrozone
Copy link
Author

@calvinchankf no its resolved. I was confused about how to configure next.js with custom server

@calvinchankf
Copy link

@calvinchankf no its resolved. I was confused about how to configure next.js with custom server

how did u solve it eventually?

@macrozone
Copy link
Author

even with custom server, you still need a next.config.js, where you put

const withCSS = require("@zeit/next-css");
module.exports = withCSS({
  cssLoaderOptions: {
    url: false,
  },
});

It works now, but i still ran in other problems like #503

Sadly, importing css files is a big problem for many frameworks, not only next.js. Another reason to avoid css...

@M4gie
Copy link

M4gie commented Jul 29, 2019

Hello,

I have the same issue, I try a lot of solutions and the only one who works for me is this one, but it's only working in dev when I run the next command. When I try to run the next build command I have this error:

> Build error occurred
{ /home/.../node_modules/react-loader-spinner/dist/loader/css/CradleLoader.css:1
.react-spinner-loader-swing div {
^

SyntaxError: Unexpected token .
    at Module._compile (internal/modules/cjs/loader.js:721:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
...

nextconfig.js :

const withCSS = require('@zeit/next-css');
module.exports = withCSS({});

.babelrc

{
    "presets": ["next/babel"],
    "plugins": ["css-modules-transform"]
}

postcss.config.js

module.exports = {
    plugins: [
        require("tailwindcss"),
        ...(process.env.NODE_ENV === `production`
            ? [
                require("@fullhuman/postcss-purgecss")({
                    content: ["./pages/**/*.js", "./components/**/*.js"],
                    defaultExtractor: content =>
                        content.match(/[A-Za-z0-9-_:/]+/g) || []
                }),
                require("autoprefixer"),
                require("cssnano")
            ]
            : [])
    ]
};

@raduchiriac
Copy link

I am on the same boat. The next.config.js did not help.

I have this inside my next().conf like this

    withSass(
      withCSS({
        cssLoaderOptions: {
          url: false,
        },
        env: {
          ...
        },
      })
    )

I only get the error when doing npm run build

@ssteiger
Copy link

What ended up working (in production build):

package.json

"@zeit/next-css": "^1.0.1",
"@zeit/next-less": "^1.0.1",
"antd": "4.0.0-rc.1"

next.config

const { IgnorePlugin } = require('webpack')
const withCSS = require('@zeit/next-css')
const withLess = require('@zeit/next-less')
const withSize = require('next-size')
const lessToJS = require('less-vars-to-js')
const cssProcessor = require('cssnano')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
const TerserPlugin = require('terser-webpack-plugin')
const OptimizeCssPlugin = require('optimize-css-assets-webpack-plugin')
const Dotenv = require('dotenv-webpack')
const fs = require('fs')
const path = require('path')

const themeVariables = lessToJS(
  fs.readFileSync(path.resolve(__dirname, './styles/antd-custom.less'), 'utf8')
)

const isDev = process.env.NODE_ENV !== 'production'

// fix antd bug in dev development
const devAntd = '@import "~antd/dist/antd.less"\n'
const stylesData = fs.readFileSync(
  path.resolve(__dirname, './styles/_styles.less'),
  'utf-8'
)
fs.writeFileSync(
  path.resolve(__dirname, './styles/self-styles.less'),
  isDev ? `${devAntd}${stylesData}` : stylesData,
  'utf-8'
)

// fix: prevents error when .css files are required by node
if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
}

const srcFolder = [path.resolve(__dirname, './src')]

module.exports = withSize(
  withCSS(
    withLess({
      lessLoaderOptions: {
        javascriptEnabled: true,
        modifyVars: themeVariables,
        localIdentName: '[local]___[hash:base64:5]'
      },
      webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
        config.plugins.push(new Dotenv({ path: './public.env' }))
        config.plugins.push(new IgnorePlugin(/^\.\/locale$/, /moment$/))
        if (isServer) {
          // deal with antd style
          const antStyles = /antd\/.*?\/style.*?/
          const origExternals = [...config.externals]
          config.externals = [
            (context, request, callback) => {
              if (request.match(antStyles)) return callback()
              if (typeof origExternals[0] === 'function') {
                origExternals[0](context, request, callback)
              } else {
                callback()
              }
            },
            ...(typeof origExternals[0] === 'function' ? [] : origExternals)
          ]
          config.module.rules.unshift({
            test: antStyles,
            use: 'null-loader'
          })
        }
        if (!dev) {
          config.plugins.push(
            ...[
              new BundleAnalyzerPlugin({
                analyzerMode: 'disabled',
                // https://github.com/th0r/webpack-bundle-analyzer#as-plugin
                generateStatsFile: true,
                // will be available at `.next/stats.json`
                statsFilename: 'stats.json'
              }),
              // minify javascript
              new TerserPlugin({
                cache: true,
                terserOptions: {
                  ecma: 6,
                  warnings: false,
                  extractComments: false, // remove comment
                  output: {
                    comments: false
                  },
                  compress: {
                    drop_console: true // remove console
                  },
                  ie8: false
                }
              }),
              // optimize css
              new OptimizeCssPlugin({
                cssProcessor,
                cssProcessorOptions: {
                  discardComments: { removeAll: true }
                },
                canPrint: true // print info to console
              })
            ]
          )
          config.module.rules.push({
            test: /\.js$/,
            include: srcFolder,
            options: {
              workerParallelJobs: 50,
              // additional node.js arguments
              workerNodeArgs: ['--max-old-space-size=1024'],
            },
            loader: 'thread-loader'
          })
          config.devtool = 'source-map'
        } else {
          config.module.rules.push({
            test: /\.js$/,
            enforce: 'pre',
            include: srcFolder,
            options: {
              configFile: path.resolve('.eslintrc'),
              eslint: {
                configFile: path.resolve(__dirname, '.eslintrc')
              }
            },
            loader: 'eslint-loader'
          })
          config.devtool = 'cheap-module-inline-source-map'
        }
        return config
      },
      webpackDevMiddleware: config => {
        // perform customizations to webpack dev middleware config
        // console.log(config, '@@')
        // important: return the modified config
        return config
      },
      serverRuntimeConfig: {
        // will only be available on the server side
        rootDir: path.join(__dirname, './'),
        PORT: isDev ? 3006 : (process.env.PORT || 5999)
      },
      publicRuntimeConfig: {
        // will be available on both server and client
        staticFolder: '/static',
        isDev // pass through env variables
      },
      env: {
        MY_COOL_VAR: ''
      }
    })
  )
)

_styles/_styles.less

@import "./antd-custom.less";

body {
  height: auto;
  background-color: #f4f4f5 !important;
}

self-styles.less

@import "./antd-custom.less";

body {
  height: auto;
  background-color: #f4f4f5 !important;
}
$ yarn run build
$ yarn run start

remember to adjust you styles folder accordingly

https://next.ant.design

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants