【问题标题】:Fix auto-generating scss type definitions (style.d.ts) Preact webpack TypeScript修复自动生成的 scss 类型定义 (style.d.ts) Preact webpack TypeScript
【发布时间】:2022-01-13 20:37:24
【问题描述】:

在 VSCode 中使用带有 Preact 10.x(几乎与 React 相同)和 TypeScript 的 webpack。

在将 Node 从 12 版更新到 14 版后(这可能(?)是问题的原因)*.scss 文件不再自动生成它们各自的类型定义文件。 p>

以前,当我运行webpack --mode development -w 时,任何新的/更改的style.scss 文件都会自动生成/重新生成它们关联的style.d.ts 文件。这不再发生,我收到错误消息

TS2307: Cannot find module style.scss or its corresponding type declarations.

如果我手动创建(或更新)style.d.ts 文件,一切正常。

如何再次修复自动生成/自动重新生成.scss 类型声明文件?

升级节点后,我确实执行了以下进一步更新:

1. Terminal>  npm cache clean --force

2. Deleted the node_modules folder in the project

3. Deleted the package-lock.json file

4. Edited the tsconfig.json file and added "baseUrl": ".",  -- e.g.
   "compilerOptions": {
      "baseUrl": ".",
      "etc etc etc": "etc etc etc",

5. Terminal>  npm install

我的 package.json:

    {
      "name": "myproject",
      "version": "1.1.0",
      "description": "myproject",
      "main": "backend/server.js",
      "scripts": {
        "start": "nodemon -r dotenv/config backend/server.js",
        "dev": "webpack --mode development -w --declaration",
        "build": "webpack --mode production"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "express": "^4.17.1",
        "knex": "^0.21.0",
        "log4js": "^6.3.0",
        "mysql": "^2.18.1",
        "preact": "10.4.8",
        "pug": "^3.0.2"
      },
      "devDependencies": {
        "@teamsupercell/typings-for-css-modules-loader": "^2.1.1",
        "@typescript-eslint/eslint-plugin": "^2.30.0",
        "@typescript-eslint/parser": "^2.30.0",
        "clean-webpack-plugin": "^3.0.0",
        "css-loader": "^3.5.3",
        "dotenv": "^8.2.0",
        "eslint": "^6.8.0",
        "eslint-plugin-react": "^7.19.0",
        "html-webpack-plugin": "^4.3.0",
        "mini-css-extract-plugin": "^0.9.0",
        "node-sass": "^4.14.1",
        "nodemon": "^2.0.3",
        "optimize-css-assets-webpack-plugin": "^5.0.3",
        "prettier": "^2.0.5",
        "prettier-eslint": "^9.0.1",
        "sass-loader": "^8.0.2",
        "style-loader": "^1.2.1",
        "terser": "^4.6.13",
        "terser-webpack-plugin": "^2.3.6",
        "ts-loader": "^7.0.2",
        "tsconfig-paths-webpack-plugin": "^3.2.0",
        "typescript": "^3.8.3",
        "webpack": "^4.43.0",
        "webpack-cli": "^3.3.11"
      }
    }

我的 tsconfig.json:

    {
      "compilerOptions": {
        "baseUrl": ".",
        "target": "es2017",
        "lib": ["dom", "esnext", "esnext.array"],
        "types": ["node"],
        "module": "esnext",
        "declaration": true,
        "moduleResolution": "node",
        "strict": true,
        "alwaysStrict": true,
        "removeComments": false,
        "sourceMap": true,
        "experimentalDecorators": true,
        "forceConsistentCasingInFileNames": true,
        "noUnusedLocals": true,
        "jsx": "react",
        "jsxFactory": "h"
      },
      "include": ["./frontend/**/*.tsx", "./frontend/**/*.ts"]
    }

我的 webpack.config.js:

    /* eslint-disable @typescript-eslint/camelcase */
    /* eslint-disable @typescript-eslint/no-var-requires */
    const path = require('path');
    const webpack = require('webpack');
    const TerserPlugin = require('terser-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');

    module.exports = (env, argv) => {
      const compressArgs = argv.mode === 'production' ? { drop_console: true } : false;
      const mode = argv.mode === 'production' ? 'bundle' : 'dev';
      const cssNamespacing = mode === 'dev' ? '[path][local]' : '[folder][hash]';
      const chunkName = mode === 'dev' ? `[name].${mode}` : '[chunkhash]';
      const cssChunkName = mode === 'dev' ? `[name].${mode}` : '[contenthash]';
      const cleanPatterns = mode === 'dev' ? ['dev.*'] : ['**/*', '!dev.*'];
      return {
        entry: `${__dirname}/frontend/index.tsx`,
        output: {
          filename: `${mode}.[contenthash].js`,
          chunkFilename: `${chunkName}.js`,
          publicPath: '/static/app',
          path: path.resolve(__dirname, './public/app'),
        },
        plugins: [
          new CleanWebpackPlugin({
            cleanOnceBeforeBuildPatterns: cleanPatterns,
          }),
          new webpack.WatchIgnorePlugin([/\.d\.ts$/]),
          new MiniCssExtractPlugin({
            ignoreOrder: true,
            filename: `${mode}.[contenthash].css`,
            chunkFilename: `${cssChunkName}.css`,
          }),
          new OptimizeCssAssetsPlugin({
            assetNameRegExp: /.(sc|c)ss$/g,
          }),
          new HtmlWebpackPlugin({
            template: 'template.html',
            filename: mode === 'dev' ? 'dev.index.html' : 'index.html',
          }),
        ],
        resolve: {
          extensions: ['.ts', '.tsx', '.js', '.css', '.scss'],
          plugins: [
            new TsconfigPathsPlugin({
              configFile: path.resolve(__dirname, 'tsconfig.json'),
            }),
          ],
        },
        module: {
          rules: [
            {
              test: /\.(sc|c)ss$/,
              use: [
                MiniCssExtractPlugin.loader,
                '@teamsupercell/typings-for-css-modules-loader',
                {
                  loader: 'css-loader',
                  options: {
                    modules: {
                      localIdentName: cssNamespacing,
                    },
                    localsConvention: 'camelCase',
                  },
                },
                'sass-loader',
              ],
            },
            {
              test: /\.tsx?$/,
              loader: 'ts-loader',
            },
          ],
        },
        optimization: {
          minimizer: [
            new TerserPlugin({
              terserOptions: {
                ecma: 8,
                warnings: false,
                compress: compressArgs,
                mangle: mode !== 'dev',
                module: false,
                keep_classnames: mode === 'dev',
                keep_fnames: mode === 'dev',
              },
            }),
          ],
          splitChunks: {
            maxSize: 200000,
            hidePathInfo: true,
            cacheGroups: {
              vendors: {
                reuseExistingChunk: true,
              },
            },
          },
        },
        stats: { children: false },
        devtool: argv.mode === 'production' ? 'source-map' : 'inline-source-map',
      };
    };

【问题讨论】:

    标签: javascript reactjs typescript webpack preact


    【解决方案1】:

    在从节点版本 12 升级到比版本 12 更新的节点的任何市长版本时,我还遇到了与 node-sass 的一些兼容性问题。 这个问题(就我而言)似乎与 node-gyp 依赖项有关,node-sass 在内部使用它与高于版本 12 的市长节点版本中断。

    到目前为止,我找到的唯一解决方案是安装节点版本管理器,并在我的计算机中安装多个节点版本,当需要在使用该依赖项的项目中工作时,只需切换到版本 12。

    查看此链接,指向适用于 Linux 或 Mac 的节点版本管理器 https://github.com/nvm-sh/nvm,以及适用于 Windows 的 https://github.com/coreybutler/nvm-windows,这是我目前正在使用的。

    【讨论】: