Webpack: SyntaxError и «Неизвестное слово» при сборке приложения SSR CRA

Обновление: здесь добавлен полный репозиторий с исходным кодом: https://github.com/jayliew/ssr-cra-graphql

Контекст: это приложение для создания и реагирования, использующее рендеринг на стороне сервера. С этой проблемой связана моя попытка заставить этот процесс сборки (веб-пакет?) Не задыхаться от использования файла .less стороннего модуля npm.

Это ошибка, которую я получаю с yarn build:

Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
SyntaxError

(1:1) /Users/username/dev/learn/react/ssr-cra-graphql/src/App.css Unknown word

> 1 | export default "/static/media/App.bb36c359.css";
    | ^

 @ ./src/App.css 3:14-176
 @ ./src/App.js
 @ ./server.js
error Command failed with exit code 2.

пакет.json:

  "name": "ssr-react-graphql",
  "author": "Eduard Gilmutdinov",
  "license": "MIT",
  "version": "1.0.0",
  "main": "index.js",
  "engines": {
    "node": ">=8.x.x"
  },
  "scripts": {
    "prebuild": "INLINE_RUNTIME_CHUNK=false react-scripts build",
    "build": "NODE_ENV=production webpack --progress --mode production --config webpack.config.server.js",
    "start": "node build/server.js",
    "start:dev": "react-scripts start",
    "test": "react-scripts test --env=jsdom",
    "heroku-postbuild": "yarn build"
  },
  "dependencies": {
    "antd": "^4.9.4",
    "apollo-cache-inmemory": "1.6.6",
    "apollo-client": "2.6.10",
    "apollo-link-http": "1.5.17",
    "css-loader": "^5.0.1",
    "express": "4.17.1",
    "graphql": "15.3.0",
    "graphql-tag": "2.10.4",
    "isomorphic-fetch": "2.2.1",
    "isomorphic-style-loader": "^5.1.0",
    "postcss-loader": "^4.1.0",
    "react": "16.13.1",
    "react-apollo": "3.1.5",
    "react-dom": "16.13.1",
    "react-helmet": "6.1.0",
    "react-router-dom": "5.2.0"
  },
  "devDependencies": {
    "@babel/core": "7.10.5",
    "@babel/preset-env": "7.10.4",
    "@babel/preset-react": "7.10.4",
    "babel-loader": "8.1.0",
    "file-loader": "6.0.0",
    "less": "^4.0.0",
    "less-loader": "^7.1.0",
    "react-scripts": "3.4.1",
    "webpack": "4.42.0",
    "webpack-cli": "3.3.12",
    "webpack-node-externals": "2.5.0"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

webpack.config.server.js:

const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: './server.js',
  output: {
    filename: 'server.js',
    path: path.resolve(__dirname, 'build')
  },
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    extensions: ['.js', '.jsx', '.less']
  },
  target: 'node',
  node: {
    __dirname: false,
  },
  externals: [nodeExternals()],
  module: {
    rules: [

      {
        test: /\.css$/,
        use: [
          'isomorphic-style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader'
        ]
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        exclude: [/\.js$/, /\.html$/, /\.json$/],
        loader: 'file-loader',
        options: {
          name: 'static/media/[name].[hash:8].[ext]',
          publicPath: '/',
          emitFile: false,
        },
      },
    ],
  },
};

Не знаете, почему вы используете подпись esnext (export default) внутри файла App.css?

tmhao2005 23.12.2020 04:09

В исходном файле export default нет src/App.css. Это каким-то образом генерируется в процессе сборки

Jay 23.12.2020 21:55

Можете ли вы поделиться воспроизводимым репо?

tmhao2005 24.12.2020 03:42

@tmhao2005 Вот оно: github.com/jayliew/ssr-cra-graphql

Jay 25.12.2020 17:58
Поиск всех неиспользуемых файлов в проекте
Поиск всех неиспользуемых файлов в проекте
Количество файлов в проекте растет по мере его развития. И если быть по-настоящему честным, их продвижение происходит в геометрической прогрессии...
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
1
4
6 737
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я протестировал ваш репозиторий и обнаружил, что нужно исправить несколько вещей, чтобы он заработал. Возвращаясь к приведенной выше ошибке, ошибка связана с настройкой file-loader, которое не имеет тестового правила, которое может соответствовать всем типам файлов, кроме [/\.js$/, /\.html$/, /\.json$/], но содержит css, тогда css файлы были переданы css правилу, в котором произошла ошибка.

Короче говоря, file-loader должен соответствовать файлу ресурсов, например: изображения/шрифты/..., но не файлу css. Итак, если правильно установить файлы test, он будет успешно собран:

// Common assets file types which are for `file-loader`
const reImage = /\.(ico|jpg|jpeg|png|gif|eot|otf|svg|webp|ttf|woff|woff2)$/;
// css files
const reScss = /\.(css|scss|sass|less)$/;

module.exports = {
  // ...
  // Bonus: you might need to exclude style files to get compiled
  externals: [nodeExternals({
    allowlist: [reScss]
  })],
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: [
          'isomorphic-style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1
            }
          },
          'postcss-loader',
          // `less` & `less-loader` are supposed to be downgraded to make it work with `antd`
          {
            loader: "less-loader",
            options: {
              lessOptions: {
                javascriptEnabled: true,
              }              
            }
          }
        ]
      },
      {
        test: reImage, // pattern for file loader
        exclude: [/\.js$/, /\.html$/, /\.json$/],
        loader: 'file-loader',
        options: {
          name: 'static/media/[name].[hash:8].[ext]',
          publicPath: '/',
          emitFile: false,
        },
      },
    ],
  },
};

Как я упоминал во встроенных комментариях, эти пакеты следует использовать с определенной версией для работы с antd:

{
  "devDependencies": {
    "less": "3.13.1",
    "less-loader": "^6.0.0",
  }
}

Другие вопросы по теме