Webpack 不适用于 Typescript 别名
Webpack is not working with Typescript aliases
我有这个 webpack.config.js
:
{
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/lib/index.ts',
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
}
]
}
]
},
plugins: [
new BundleDeclarationsWebpackPlugin({
entry: "./source/lib/index.ts",
outFile: "./index.d.ts"
})
],
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'lib'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
}
因为你可以看到我将一个库与 webpack 捆绑在一起,将 node_modules 保持为外部。
还有这个tsconfig.json
:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "ES5",
"strictNullChecks": true,
"lib": [
"ES2021"
],
"outDir": "../dist",
"sourceMap": true,
"declaration": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./lib/*"
],
"@lib/*": [
"./lib/*"
],
"@bin/*": [
"./bin/*"
]
}
},
"plugins": [
{
"transform": "typescript-transform-paths"
},
{
"transform": "typescript-transform-paths",
"afterDeclarations": true
}
],
"include": [
"lib",
"bin"
]
}
当我执行 tsc -p source
时一切正常,即使我的需求中有“@”路径
但是当我用 webpack 做同样的事情时,我得到了这些错误:
ERROR in ./source/lib/index.ts 50:16-42
Module not found: Error: Can't resolve '@/utils/cleaner' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 51:19-48
Module not found: Error: Can't resolve '@/utils/askConfirm' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 52:16-42
Module not found: Error: Can't resolve '@/utils/options' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 53:13-45
Module not found: Error: Can't resolve '@/interfaces/exported' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 54:13-32
Module not found: Error: Can't resolve '@/errors' in '/home/euber/Github/mongo-cleaner/source/lib'
webpack 怎么可能忽略@?
要获得更多信息并能够重现它,只需查看 this repo
更新:
我也试过这个答案,但它不起作用:
webpack.config.js
alias: {
'@': path.resolve(__dirname, 'lib'),
'@lib': path.resolve(__dirname, 'lib'),
'@bin': path.resolve(__dirname, 'bin')
}
错误:
ERROR in ./source/lib/index.ts 50:16-42
Module not found: Error: Can't resolve '@/utils/cleaner' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 51:19-48
Module not found: Error: Can't resolve '@/utils/askConfirm' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 52:16-42
Module not found: Error: Can't resolve '@/utils/options' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 53:13-45
Module not found: Error: Can't resolve '@/interfaces/exported' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 54:13-32
Module not found: Error: Can't resolve '@/errors' in '/home/euber/Github/mongo-cleaner/source/lib'
您已经为 typescript 编译器指定了路径别名,但您还需要指定 aliases for webpack 因为 webpack 以自己的方式解析模块。
因此您需要更新 webpack 配置,如下例所示:
{
...
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@': path.resolve(__dirname, 'source/lib'),
'@lib': path.resolve(__dirname, 'source/lib'),
'@bin': path.resolve(__dirname, 'source/bin')
}
}
...
}
@Mikhail Sereniti 的回答是可行的,但是一个模块允许自动处理这个问题。
我添加了这个:
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
它奏效了。
完整代码:
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const BundleDeclarationsWebpackPlugin = require('bundle-declarations-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const libConfig = {
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/lib/index.ts',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
},
module: {
rules: [
{
test: /\.ts$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
}
]
}
]
},
plugins: [
new BundleDeclarationsWebpackPlugin({
entry: "./source/lib/index.ts",
outFile: "./index.d.ts"
})
],
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'lib'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
};
const binConfig = {
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/bin/index.ts',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
},
plugins: [
new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true })
],
module: {
rules: [
{
test: /\.ts?$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
},
{
loader: 'shebang-loader'
}
]
}
]
},
externals: [{
'../lib/index': {
amd: '../lib/index',
root: 'mongo-cleaner',
commonjs: '../lib/index',
commonjs2: '../lib/index'
},
}, nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'bin'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
};
module.exports = [
libConfig,
binConfig
];
编辑:
我还发现了另一个错误。我将 ttypescript
用于类似目的,但“插件”关键字应该在编译器选项中。
所以,即使没有 TsconfigPathsPlugin
东西,通过像这样更改 tsconfig.json
问题也解决了:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "ES5",
"strictNullChecks": true,
"lib": [
"ES2021"
],
"outDir": "../dist",
"sourceMap": true,
"declaration": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./lib/*"
],
"@lib/*": [
"./lib/*"
],
"@bin/*": [
"./bin/*"
]
},
"plugins": [
{
"transform": "typescript-transform-paths"
},
{
"transform": "typescript-transform-paths",
"afterDeclarations": true
}
],
},
"include": [
"lib",
"bin"
]
}
我有这个 webpack.config.js
:
{
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/lib/index.ts',
},
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
}
]
}
]
},
plugins: [
new BundleDeclarationsWebpackPlugin({
entry: "./source/lib/index.ts",
outFile: "./index.d.ts"
})
],
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'lib'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
}
因为你可以看到我将一个库与 webpack 捆绑在一起,将 node_modules 保持为外部。
还有这个tsconfig.json
:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "ES5",
"strictNullChecks": true,
"lib": [
"ES2021"
],
"outDir": "../dist",
"sourceMap": true,
"declaration": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./lib/*"
],
"@lib/*": [
"./lib/*"
],
"@bin/*": [
"./bin/*"
]
}
},
"plugins": [
{
"transform": "typescript-transform-paths"
},
{
"transform": "typescript-transform-paths",
"afterDeclarations": true
}
],
"include": [
"lib",
"bin"
]
}
当我执行 tsc -p source
时一切正常,即使我的需求中有“@”路径
但是当我用 webpack 做同样的事情时,我得到了这些错误:
ERROR in ./source/lib/index.ts 50:16-42
Module not found: Error: Can't resolve '@/utils/cleaner' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 51:19-48
Module not found: Error: Can't resolve '@/utils/askConfirm' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 52:16-42
Module not found: Error: Can't resolve '@/utils/options' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 53:13-45
Module not found: Error: Can't resolve '@/interfaces/exported' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 54:13-32
Module not found: Error: Can't resolve '@/errors' in '/home/euber/Github/mongo-cleaner/source/lib'
webpack 怎么可能忽略@?
要获得更多信息并能够重现它,只需查看 this repo
更新:
我也试过这个答案,但它不起作用:
webpack.config.js
alias: {
'@': path.resolve(__dirname, 'lib'),
'@lib': path.resolve(__dirname, 'lib'),
'@bin': path.resolve(__dirname, 'bin')
}
错误:
ERROR in ./source/lib/index.ts 50:16-42
Module not found: Error: Can't resolve '@/utils/cleaner' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 51:19-48
Module not found: Error: Can't resolve '@/utils/askConfirm' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 52:16-42
Module not found: Error: Can't resolve '@/utils/options' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 53:13-45
Module not found: Error: Can't resolve '@/interfaces/exported' in '/home/euber/Github/mongo-cleaner/source/lib'
ERROR in ./source/lib/index.ts 54:13-32
Module not found: Error: Can't resolve '@/errors' in '/home/euber/Github/mongo-cleaner/source/lib'
您已经为 typescript 编译器指定了路径别名,但您还需要指定 aliases for webpack 因为 webpack 以自己的方式解析模块。
因此您需要更新 webpack 配置,如下例所示:
{
...
resolve: {
extensions: ['.ts', '.js'],
alias: {
'@': path.resolve(__dirname, 'source/lib'),
'@lib': path.resolve(__dirname, 'source/lib'),
'@bin': path.resolve(__dirname, 'source/bin')
}
}
...
}
@Mikhail Sereniti 的回答是可行的,但是一个模块允许自动处理这个问题。
我添加了这个:
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
它奏效了。
完整代码:
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const BundleDeclarationsWebpackPlugin = require('bundle-declarations-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const libConfig = {
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/lib/index.ts',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
},
module: {
rules: [
{
test: /\.ts$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
}
]
}
]
},
plugins: [
new BundleDeclarationsWebpackPlugin({
entry: "./source/lib/index.ts",
outFile: "./index.d.ts"
})
],
externals: [nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'lib'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
};
const binConfig = {
target: 'node',
mode: 'production',
// devtool: 'source-map',
entry: {
index: './source/bin/index.ts',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [new TsconfigPathsPlugin({
configFile: './source/tsconfig.json',
extensions: ['.ts', '.js']
})]
},
plugins: [
new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true })
],
module: {
rules: [
{
test: /\.ts?$/,
include: path.resolve(__dirname, 'source'),
use: [
{
loader: 'ts-loader',
options: {
compiler: 'ttypescript'
}
},
{
loader: 'shebang-loader'
}
]
}
]
},
externals: [{
'../lib/index': {
amd: '../lib/index',
root: 'mongo-cleaner',
commonjs: '../lib/index',
commonjs2: '../lib/index'
},
}, nodeExternals()],
output: {
path: path.resolve(__dirname, 'bundled', 'bin'),
filename: 'index.js',
library: 'mongo-cleaner',
libraryTarget: 'umd',
globalObject: 'this',
umdNamedDefine: true,
}
};
module.exports = [
libConfig,
binConfig
];
编辑:
我还发现了另一个错误。我将 ttypescript
用于类似目的,但“插件”关键字应该在编译器选项中。
所以,即使没有 TsconfigPathsPlugin
东西,通过像这样更改 tsconfig.json
问题也解决了:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "commonjs",
"target": "ES5",
"strictNullChecks": true,
"lib": [
"ES2021"
],
"outDir": "../dist",
"sourceMap": true,
"declaration": true,
"baseUrl": ".",
"paths": {
"@/*": [
"./lib/*"
],
"@lib/*": [
"./lib/*"
],
"@bin/*": [
"./bin/*"
]
},
"plugins": [
{
"transform": "typescript-transform-paths"
},
{
"transform": "typescript-transform-paths",
"afterDeclarations": true
}
],
},
"include": [
"lib",
"bin"
]
}