我在这样的项目中导入了:
import { ytheme } from "./ytheme.js";
为什么?因为: https://www.typescriptlang.org/docs/handbook/2/modules.html#es-module-syntax 和 在 Typescript 编译期间(ES6 模块)在相对导入语句上附加 .js 扩展名(第一个答案)
Webpack 尝试解决它并出现错误:
Field 'browser' doesn't contain a valid alias configuration
<...>\src\client\components\ytheme.js.ts doesn't exist
这显然行不通。正确的路径应该是:
<...>\src\client\components\ytheme.ts
问题:如何配置 webpack 在解析导入时在附加“.ts”之前删除“.js”?
============详情==========
webpack.config.js:
const path = require("path");
const fs = require("fs");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin").CleanWebpackPlugin;
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const isDevelopment = process.env.NODE_ENV !== "production";
const pathes = (() => {
const proj = path.resolve(__dirname);
const projParts = proj.split(path.sep);
const projName = projParts[projParts.length - 1];
const root = path.resolve(__dirname, "");
return {
root,
proj,
projName,
resources: path.resolve(proj, "resources"),
bundles: path.resolve(proj, "lib/bundles", projName),
};
})();
for (let k in pathes) console.log(`pathes.${k} = ${pathes[k]}`);
const NODE_ENV = "development";
let BUILD_DATE = new Date();
BUILD_DATE.setTime(BUILD_DATE.getTime() + 3 * 60 * 60 * 1000);
BUILD_DATE = JSON.stringify(BUILD_DATE);
BUILD_DATE = BUILD_DATE.substr(1, 10) + " " + BUILD_DATE.substr(12, 8);
console.log("");
console.log("BUILD_DATE = " + BUILD_DATE);
console.log("");
let package_json;
let manifest_json;
package_json = JSON.parse(fs.readFileSync(path.resolve(pathes.root, "package.json"), { encoding: "utf-8" }));
manifest_json = JSON.parse(fs.readFileSync(path.resolve(pathes.resources, "manifest.json"), { encoding: "utf-8" }));
let tsconf = eval("(()=>(" + fs.readFileSync("tsconfig.json", "utf-8") + "))()");
let moduleAliases = {};
for (let k in tsconf.compilerOptions.paths) {
let v = tsconf.compilerOptions.paths[k];
moduleAliases[k] = path.resolve(pathes.root, "ts_out", v[0]);
}
let excludedModules = [
"fs",
"sql-prettier",
"prettier",
"express",
"socket.io",
"better-sqlite3",
"sqlite3",
"child_process",
];
module.exports = {
// TODO REMOVED ON 2020-13-11
// node: {
// fs: "empty",
// child_process: "empty",
// },
mode: "development",
entry: [path.resolve(pathes.proj, "src/client/indexSmall.tsx")],
devtool: "inline-source-map",
devServer: {
contentBase: "./resources",
hot: true,
},
resolve: {
fallback: {
crypto: false,
fs: false,
child_process: false,
path: false,
constants: false,
util: false,
assert: false,
stream: false,
// crypto: require.resolve("crypto-browserify"),
// fs:null,
},
// root: path.join(pathes.proj, 'js'),
// modulesDirectories: ['node_modules'],
extensions: ["", ".ts", ".tsx", ".js", ".jsx", ".json"],
alias: {
"react-dom": "@hot-loader/react-dom",
...moduleAliases,
},
},
output: {
path: pathes.bundles,
filename: "bundle.js",
},
module: {
rules: [
{
test: (modulePath0) => {
let modulePath = modulePath0.split(path.sep);
for (let excludedModule of excludedModules) if (modulePath.includes(excludedModule)) return true;
return false;
},
use: "null-loader",
},
{
test: /\.css$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
],
},
{
test: /\.scss$/,
use: [
"style-loader", // creates style nodes from JS strings
"css-loader", // translates CSS into CommonJS
"sass-loader", // compiles Sass to CSS, using Node Sass by default
],
},
{
test: /\.(j|t)sx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
babelrc: false,
presets: ["@babel/preset-typescript", "@babel/preset-react"],
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
"@babel/proposal-optional-chaining",
["@babel/proposal-class-properties", { legacy: true }],
"@babel/proposal-object-rest-spread",
// "react-hot-loader/babel",
[
"module-resolver",
{
root: ["./"],
alias: moduleAliases,
},
],
// "@babel/transform-modules-commonjs",
],
},
},
},
],
},
plugins: [
new webpack.DefinePlugin({
BROWSER: "true",
"process.env.BROWSER": "true",
NODE_ENV: JSON.stringify(NODE_ENV),
BUILD_DATE: JSON.stringify(BUILD_DATE),
// BASE_URL:JSON.stringify(private_js ? private_js.url : 'http://localhost')
}),
new CleanWebpackPlugin(),
// new webpack.NamedModulesPlugin(), // TODO REMOVED ON 2020-13-11
new HtmlWebpackPlugin({ title: manifest_json.name }),
isDevelopment && new webpack.HotModuleReplacementPlugin(),
isDevelopment && new ReactRefreshWebpackPlugin(),
],
// watchOptions : {
// aggregateTimeout : 300
// },
// "cheap-inline-module-source-map"
};
// console.log('YYAWEBPACK', JSON.stringify(module.exports.resolve.alias,null, "\t"));
我运行开发服务器的命令:
webpack-cli serve --mode development --config webpack.frontend.config.js
完全错误:
ERROR in ./src/client/indexSmall.tsx 7:0-48
Module not found: Error: Can't resolve './components/ytheme.js' in 'D:\b\Mine\GIT_Work\yatasks_one_api\src\client'
resolve './components/ytheme.js' in 'D:\b\Mine\GIT_Work\yatasks_one_api\src\client'
using description file: D:\b\Mine\GIT_Work\yatasks_one_api\package.json (relative path: ./src/client)
Field 'browser' doesn't contain a valid alias configuration
using description file: D:\b\Mine\GIT_Work\yatasks_one_api\package.json (relative path: ./src/client/components/ytheme.js)
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js doesn't exist
.ts
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js.ts doesn't exist
.tsx
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js.tsx doesn't exist
.js
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js.js doesn't exist
.jsx
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js.jsx doesn't exist
.json
Field 'browser' doesn't contain a valid alias configuration
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js.json doesn't exist
as directory
D:\b\Mine\GIT_Work\yatasks_one_api\src\client\components\ytheme.js doesn't exist
webpack 5.41.1 compiled with 2 errors in 2120 ms
i 「wdm」: Failed to compile.
作为解决方法,以下代码片段似乎有效:
{ // webpack.config.cjs
plugins: [
new webpack.NormalModuleReplacementPlugin(/.*/, function (resource) {
const lowerCaseRequest = resource.request.toLowerCase();
if (
!lowerCaseRequest.includes("node_modules") &&
lowerCaseRequest.endsWith(".js") &&
lowerCaseRequest[0] === "." &&
resource.context.startsWith(path.resolve(__dirname))&&
!resource.context.toLowerCase().includes("node_modules")
) {
resource.request = resource.request.substr(0, resource.request.length - 3) + ".ts";
resource.request });
}
}),
...]
}
现在有一个更简单的解决方案,webpack 有一个功能可以解析使用
.js
扩展导入的 TypeScript 文件:https://webpack.js.org/configuration/resolve/#resolveextensionalias