I've deleted CRA and configured webpack/babel on my own. Now I have problems with dynamic imports.
This works fine:
import("./" + "CloudIcon" + ".svg")
.then(file => {
console.log(file);
})
This doesn't work:
const name = 'CloudIcon';
import("./" + name + ".svg")
.then(file => {
console.log(file);
})
I've tried to export files with different types. It didn't work. Have tried to use Webpack Magic Comments, but didn't help either.
I suppose, that something is wrong with my webpack/babel settings, but what?
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
}
The problem was the extensions array in webpack
'extensions': ['', '.js', '.jsx', '.ts', '.tsx']
I changed it to this
'extensions': ['.js', '.jsx', '.ts', '.tsx', '...']
And now everything works fine.