Webpack cant resolve TypeScript modules - javascript

I build a relay small webpack and typescript demo to play with.
If i run webpack with the webpack.config.js i get this error:
ERROR in ./js/app.ts
Module not found: Error: Can't resolve './MyModule' in '/Users/timo/Documents/Dev/Web/02_Tests/webpack_test/js'
# ./js/app.ts 3:17-38
I have no clue what the problem could be. The module export should be correct.
Folder Structure
webpack.config.js
const path = require('path');
module.exports = {
entry: './js/app.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{test: /\.ts$/, use: 'ts-loader'}
]
}
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"suppressImplicitAnyIndexErrors": true,
"strictNullChecks": false,
"lib": [
"es5", "es2015.core", "dom"
],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist"
},
"include": [
"js/**/*"
]
}
src/app.js
import { MyModule } from './MyModule';
let mym = new MyModule();
console.log('Demo');
mym.createTool();
console.log(mym.demoTool(3,4));
src/MyModule.ts
export class MyModule {
createTool() {
console.log("Test 123");
}
demoTool(x:number ,y:number) {
return x+y;
}
};
src/index.html
<html>
<head>
<title>Demo</title>
<base href="/">
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>

Webpack does not look for .ts files by default. You can configure resolve.extensions to look for .ts. Don't forget to add the default values as well, otherwise most modules will break because they rely on the fact that the .js extension is automatically used.
resolve: {
extensions: ['.ts', '.js', '.json']
}

Tried all the suggestions above and it still didn't work.
Ended up being the tiniest detail:
In webpack.js, instead of:
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
The ordering should be:
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
Don't know why this is necessary, and to be quite honest, I'm beyond caring at this point...

Leaving this here for posterity, but I had this exact same issue and my problem was that my entry path was not relative but absolute. I changed entry from:
entry: 'entry.ts'
to
entry: './entry.ts'

I'm a bit late to the party, but is better to use:
resolve: {
extensions: ['.jsx', '.ts', '.tsx', '...']
}
... means that we'll not overwrite the default, only add to it

I'm using tsconfig instead of webpack which also compiles the submodule to a bundle (index.js).
The issue for me was that I had forgotten to compile the submodule (ie run tsc to generate index.js) before referencing it from outside.

Related

Babel module resolver not working with react-native

My babel module resolver is not working with React-Native (neither does intellij in VScode)
Here, Is my babel config
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./'],
alias: {
'#assets': './src/assets',
'#modules': './src/modules',
'#config': './src/config',
'#utils': './src/utils',
},
},
],
],
};
And jsconfig.json
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"#assets": ["./assets"],
"#modules": ["./modules"],
"#config": ["./config"],
"#utils": ["./utils"]
}
}
}
I changed import for one of my files and this is the error I get when I executed the build command from Xcode
Error: Error loading assets JSON from Metro. Ensure you've followed
all expo-updates installation steps correctly. Unable to resolve
module ../../modules/store/components/Filters from
src/utils/Router.js:
None of these files exist:
Where I imported the file like this
import Filters from '#modules/store/components/Filters';
I had the same problem, I just removed the '#' from my aliases and it seems working fine now.
Here is my babel.config.js
module.exports = function (api) { ■ File is a CommonJS module; it may be converted to an ES6 module.
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: [
[
require.resolve("babel-plugin-module-resolver"),
{
root: ["./src/"],
alias: {
// define aliases to shorten the import paths
components: "./src/components",
containers: "./src/containers",
contexts: "./src/contexts",
interfaces: "./src/interfaces",
organizer: "./src/screens/organizer",
screens: "./src/screens",
},
extensions: [".js", ".jsx", ".tsx", ".ios.js", ".android.js"],
},
],
],
};
};
Try resetting the cache, if above suggested answers don't work
react-native start --reset-cache
This worked for me. For more info see here
Change your module-resolver's root to ['./src/']:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src/'], // <-- here ✅
alias: {
'#assets': './src/assets',
'#modules': './src/modules',
'#config': './src/config',
'#utils': './src/utils',
},
},
],
],
};

Jest configuration error in React+Typescript+Webpack project

I have faced following problem.
FYI, I am a beginner for the Jest, so please let me know what's wrong in configuring Jest.
webpack.config.js
...
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json', '.scss'],
alias: {
'webextension-polyfill-ts': path.resolve(
path.join(__dirname, 'node_modules', 'webextension-polyfill-ts')
),
reducers: path.resolve(__dirname, 'source/redux'),
routers: path.resolve(__dirname, 'source/routers'),
source: path.resolve(__dirname, 'source'),
...
},
},
...
Here's the Jest configuration in package.json
"jest": {
...
"moduleNameMapper": {
"^reducers": "<rootDir>/source/redux/$1",
"^routers": "<rootDir>/source/routers/$1",
"^source": "<rootDir>/source/$1",
...
}
...
}
But I got following error while run a test file.
Configuration error:
Could not locate module source-map-support mapped as:
/Volumes/WORK/Development/project/source/$1.
Please check your configuration for these entries:
{
"moduleNameMapper": {
"/^source/": "/Volumes/WORK/Development/project/source/$1"
},
"resolver": undefined
}
The issue looks like from you set the wrong pattern for moduleNameMapper. The right one is supposed to be:
{
"moduleNameMapper": {
"^reducers/(.*)$": "<rootDir>/source/redux/$1", // You missed the 2nd part `/(.*)`
// ...
...
}
}

Can't debug React+Typescript in browser. JS files not generated in output directory

I've configured Typescript with Webpack for a React project. Problem is, I can't debug from my browser using the .JS source. Only the bundle.js is being generated.
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"module": "commonjs",
"target": "es6",
"jsx": "react"
},
"include": [
"./src/**/**/*"
]
}
webpack.config.js (UPDATED)
const path = require('path')
module.exports = {
mode: 'development',
entry: "./src/index.tsx",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, './dist')
},
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
devtool: 'source-map',
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "ts-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js?$/, loader: "source-map-loader" }
]
},
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
externals: {
"react": "React",
"react-dom": "ReactDOM",
"react-router-dom": "ReactRouterDOM",
"reactstrap": "Reactstrap",
"flux" : "Flux"
}
};
Now this is my output in my dist directory
.
├── bundle.js
└── bundle.js.map
My intention is to get the .js sources for all my .tsx files so I can debug in my browser by just using the console's source tab.
You'll need to add this to your webpack config and read the appopriate documentation.
devtool: 'source-map',
I also encountered the same problem before.
set webpack config devtool to cheap-module-eval-source-map
devtool: 'cheap-module-eval-source-map'

eslint error showing with webpack alias

In my webpack config. I defined aliases
alias: {
components: 'src/components/',
config: 'src/config/'
}
When I import a module from this path an eslint error occurred.
import ShadowWrapper from 'components/ShadowWrapper'
error 'components' should be listed in the project's dependencies. Run 'npm i -S components' to add it import/no-extraneous-dependencies
Thanks, Pranav for the solution to this issue!
I add some code to this post to make it more practical for others.
First of all, in webpack config file I had defined this alias:
alias:{
components: path.resolve(__dirname, "src", "components")
}
That allow me to import components in my app in that way:
import NewsFeed from 'components/NewsFeed'
I have installed eslint-import-resolver-webpack plugin and put below code into .eslintrc.js or .eslintrc file :
settings: {
'import/resolver': {
alias: {
map: [
['components', './src/components']
]
}
}
That's it after running linter I got rid of Unable to resolve path to module 'components/NewsFeed' error message
Hope it will be helpful for some of you!
Here is what worked for me:
I installed eslint-import-resolver-alias as dev dependency:
npm install eslint-plugin-import eslint-import-resolver-alias --save-dev
In the Webpack config (in my case, it was Vue config, which is merged with Webpack config by Vue-cli), I added a few aliases:
resolve: {
extensions: ['.js', '.vue', '.json', '.less'],
alias: {
Site: path.resolve(__dirname, 'src/site'),
Admin: path.resolve(__dirname, 'src/admin'),
Common: path.resolve(__dirname, 'src/common'),
Assets: path.resolve(__dirname, 'src/common/assets'),
Configs: path.resolve(__dirname, 'src/common/configs'),
Style: path.resolve(__dirname, 'src/common/style')
}
}
In the .eslintsrc (or .eslintsrc.js, if you use that), I added the plugin and maps for these aliases, as follows:
"extends": ["plugin:import/recommended"],
"settings": {
"import/resolver": {
"alias": {
"map": [
["Site", "./src/site"],
["Admin", "./src/admin"],
["Common", "./src/common"],
["Assets", "./src/common/assets"],
["Configs", "./src/common/configs"],
["Style", "./src/common/style"]
]
},
"extensions": [".js", ".less", ".json", ".vue"]
}
}
I have added extensions for clarity and some good measures, which you can choose to not use for yourself.
Optional:
If you use VS Code and want these aliases working with the path intellisense, add a file jsconfig.json at the root, and specify your alias paths:
{
"compilerOptions": {
"target": "esnext",
"allowSyntheticDefaultImports": false,
"baseUrl": "./",
"paths": {
"~/*": ["src/*"],
"Root/*": ["src/*"],
"Site/*": ["src/site/*"],
"Admin/*": ["src/admin/*"],
"Common/*": ["src/common/*"],
"Assets/*": ["src/common/assets/*"],
"Configs/*": ["src/common/configs/*"],
"Style/*": ["src/common/style/*"]
}
},
"exclude": ["node_modules", "dist"]
}
There are additional settings for React and Typescript. Check the documentation at official site.
This issue can be resolved by using the eslint-import-resolver-webpack
Another way, without mapping aliases between webpack.config.js and .eslintrc.
You can use eslint-import-resolver-webpack and setup you .eslintrc file like this:
{
"extends": [
"plugin:import/recommended"
],
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"],
"moduleDirectory": [
"node_modules",
"src"
]
}
}
}
}

Eslint errorring importing jsx without extension

I am trying, in es6, to import jsx files without requiring the .jsx extension:
import LoginErrorDialog from './LoginErrorDialogView';
Not:
import LoginErrorDialog from './LoginErrorDialogView.jsx';
While I have got webpack to import in this fashion successfully:
export default {
entry: './src/ui/js/app.js',
output: {
publicPath: '/',
filename: 'bundle.js'
},
resolve: {
extensions: ['.js', '.jsx'],
Eslint (esw webpack.config.* ./ --color --ext .js --ext .jsx) is still errorring.
Unable to resolve path to module './LoginView' import/no-unresolved
Any ideas?
I had the same issue here, and I fixed adding extra configuration in my .eslintrc.
In the extends property add:
"plugin:import/react"
In the settings property add:
"import/resolver": {
"node": {
"extensions": [".js",".jsx"]
}
}
Your .eslintrc will look like:
{
"extends": [
...
"plugin:import/react",
...
],
...
"settings": {
"import/resolver": {
"node": {
"extensions": [".js",".jsx"]
}
}
},
...
}
Add to rule section, below rule
"import/extensions": [0, { "js": "always" }]

Categories