webpack 使用动态导入时“找不到模块”

huwehgph  于 2022-11-13  发布在  Webpack
关注(0)|答案(1)|浏览(448)

我已经删除了CRA,并自行配置了webpack/babel。现在我遇到了动态导入的问题。

这样做效果很好:

import("./" + "CloudIcon" + ".svg")
  .then(file => {
  console.log(file);
})

这是行不通的:

const name = 'CloudIcon';

import("./" + name + ".svg")
  .then(file => {
  console.log(file);
})

我试过导出不同类型的文件,但没有成功。我试过使用Webpack Magic Comments,但也没有帮助。
我想,我的webpack/babel设置有问题,但是什么呢?
babel.config.js:

const plugins = [
  "@babel/syntax-dynamic-import",
  ["@babel/plugin-transform-runtime"],
  "@babel/transform-async-to-generator",
  "@babel/plugin-proposal-class-properties"
];

if (process.env.NODE_ENV === 'development') {
  plugins.push('react-refresh/babel'); 
}

module.exports = {
  presets: [[
    "@babel/preset-env", {
      "debug": false,
      "modules": false,
      "useBuiltIns": false
    }],
    ['@babel/preset-react', {throwIfNamespace: false}],
    '@babel/preset-typescript'
  ],
  plugins,
};

webpack.config.js:

require('dotenv').config();
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');

const reactAppVars = (() => {
  const obj = {};
  for (let key in process.env) {
    if (key.startsWith('REACT_APP_')) obj[key] = process.env[key];
  }
  return obj;
})();

const target = process.env['NODE_ENV'] === 'production' ? 'browserslist' : 'web';

const plugins = [
  new webpack.EnvironmentPlugin({'NODE_ENV': process.env['NODE_ENV'], 'PUBLIC_URL': '', ...reactAppVars}),
  new HtmlWebpackPlugin({template: path.resolve(__dirname, '../public/index.html')}),
  new MiniCssExtractPlugin({filename: '[name].[contenthash].css'}),
  new webpack.ProvidePlugin({process: 'process/browser'}),
  new webpack.ProvidePlugin({"React": "react"}),
];

if (process.env['SERVE']) plugins.push(new ReactRefreshWebpackPlugin());

const proxy = {
//Proxy settings
}

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, "../build"),
    assetModuleFilename: '[path][name].[ext]'
  },
  plugins,
  devtool: 'source-map',
  devServer: {
    static: {
      directory: path.resolve(__dirname, "../public"),
    },
    proxy,
    port: 9999,
    hot: true,
  },

  module: {
    rules: [
      { test: /\.(html)$/, use: ['html-loader'] },
      {
        test: /\.(s[ac]|c)ss$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader'
        ]
      },
      {
        test: /\.less$/i,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true
              }
            }
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif|webp|ico)$/i,
        type: process.env['NODE_ENV'] === 'production' ? 'asset' : 'asset/resource'
      },
      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        use: ['@svgr/webpack', {
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]'
          }
        }],
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/i,
        type: process.env['NODE_ENV'] === 'production' ? 'asset' : 'asset/resource'
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory: true,
          }
        }
      },
      {
        test: /\.([cm]?ts|tsx)$/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [
              "@babel/preset-env",
              "@babel/preset-react",
              "@babel/preset-typescript",
            ]
          }
        }
      },
      {
        test: /\.md$/,
        loader: "raw-loader"
      },
    ],
  },
  resolve: {
    'roots': [path.resolve('./src')],
    'extensions': ['', '.js', '.jsx', '.ts', '.tsx'],
    extensionAlias: {
      ".js": [".js", ".ts"],
      ".cjs": [".cjs", ".cts"],
      ".mjs": [".mjs", ".mts"]
    },
    fallback: {
      'process/browser': require.resolve('process/browser')
    }
  },
  mode: process.env['NODE_ENV'],
  target
}
k10s72fa

k10s72fa1#

当你定义了导入路径后,webpack会将代码包含在已经存在块中。当你有一个动态导入(转换为正则表达式)时,它会将所有对应于这个正则表达式的文件放在一个不同的块中。
很难从细节上判断你是否提供了这些额外的块,浏览器是否可以到达它们。网络和服务器日志是一个很好的开始。
https://webpack.js.org/guides/code-splitting/#prefetchingpreloading-modules

相关问题