Absolute Imports not working with WebPack - javascript

I'm trying to setup up absolute imports, but it seems my webpack configs are wrong and the entry point it starts from is relative and not from ./src
I've looked through the webpack docs and they recommend adding an entry point, which I have but still nothing.
Error I get:
Module not found: Error: Can't resolve 'contexts' in '/Users/gurneet/Desktop/Projects/projectfrontend/src/components/Home'
structure:
Project
|- src
| - components
| - Home
| - Featured.tsx
| - contexts
| - index.ts
| - AllDataProvider.tsx
|-package.json
|-tsconfig.json
|-webpack.config.js
// FEATURED.TSX
import React from 'react';
import {useData} from '../../contexts'; // this works
import {useData} from 'contexts'; // this doesn't work.
Even though when I hover over both the imports they points to the say index.ts file that has all the exports.
// WEBPACK
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
devtool: 'source-map',
devServer: {
historyApiFallback: true,
},
entry: './src',
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
{
test: /\.svg/,
use: {
loader: 'svg-url-loader',
options: {
// make all svg images to work in IE
iesafe: true,
},
},
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'public/_redirects' },
],
}),
],
};
//TSCONFIG
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"baseUrl": "src",
"paths": {
"src/*": ["src/*"]
},
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
Where am i going wrong?

Related

`Cannot read properties of undefined` for enum after bundling with webpack

I have a React Library that I want to make buildable using Webpack. The library is written using Typescript. It seems everything is working, but for some reason enums aren't.
When I install the library into my React App, I find Cannot read properties of undefined in the browser console for the enum.
I've tried looking in the outputted bundle and it does appear that the enum is being compiled into the bundle. I feel like I must have a misconfiguration somewhere. Before I was able to bundle with microbundle-crl which we're moving from in favour of Webpack.
Here is my webpack.config.js file:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const DtsBundleWebpack = require('dts-bundle-webpack');
module.exports = {
mode: 'production',
entry: './src/index.tsx',
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
resolve: {
extensions: ['.tsx', '.ts', '.json', 'jsx', '.js'],
},
devtool: 'inline-source-map',
module: {
rules: [
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, //Extract css into files
'css-loader', // Turns css into commonjs
],
},
{
test: /\.pcss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader', // Turns css into commonjs
'postcss-loader'
]
},
],
},
plugins: [
new MiniCssExtractPlugin({ filename: 'randomcompany-components.css' }),
new DtsBundleWebpack({
name: '#randomcompany/components',
main: './dist/src/index.d.ts',
out: '../index.d.ts',
}),
],
};
My tsconfig.json is as follows:
{
"compilerOptions": {
"outDir": "dist",
"module": "esnext",
"lib": ["dom", "esnext"],
"types": ["react", "react-scripts"],
"moduleResolution": "node",
"jsx": "react",
"sourceMap": true,
"declaration": true,
"declarationDir": "dist",
"esModuleInterop": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"isolatedModules": true,
"preserveConstEnums": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true
},
"include": ["src", "src/lang"],
"exclude": ["node_modules", "dist", "src/stories"]
}
My enum is in this format:
export enum Test {
TestOne = "Test One",
TestTwo = "Test Two",
TestThree = "Test Three"
};
export default Test;
You should write it like below:
const Test = {
TestOne: "Test One",
TestTwo: "Test Two",
TestThree: "Test Three",
};
export default Test;
But in my opinion, using enum makes your bundle file a little bit heavy, just advise. use simple JavaScript objects.

ts-loader not working (You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file)

I'm trying to add TS to a JS project and it doesn't seem like webpack is picking up ts-loader for .tsx files. I've tried using babel and awesome-ts-loader and nothing that other people have done seem to work.
Full error:
ERROR in ./src/components/Account/Test.tsx 3:0 Module parse failed:
The keyword 'interface' is reserved (3:0) You may need an appropriate
loader to handle this file type, currently, no loaders are configured
to process this file. See https://webpack.js.org/concepts#loaders
webpack config
const includePaths = [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'test'),
path.resolve(__dirname, 'package.json'),
];
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'ts-loader',
},
],
include: includePaths,
},
{
test: /\.jsx?$/,
use: {
loader: 'babel-loader',
},
include: includePaths,
},
{
test: /\.scss$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
query: moduleStyle,
},
{
loader: 'postcss-loader',
},
{
loader: 'sass-loader',
},
],
include: includePaths,
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader'],
include: includePaths,
},
{
test: /\.(gif|png|jpg|eot|woff|ttf|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'web/[hash].[ext]',
},
},
],
include: includePaths,
},
],
},
tsconfig
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"sourceMap": true,
"module": "ES2015",
"target": "es6" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"app/*": ["src/*"]
},
"allowJs": true,
"allowSyntheticDefaultImports": true,
"jsx": "react"
},
"include": ["src"]
}
Test component that I'm trying to import in JS file
import React from 'react';
interface TestComponentProps {
prop1: string;
prop2: string;
}
const TestComponent: React.FC<TestComponentProps> = ({ prop1, prop2 }) => {
return (
<div>
Test Component
<div>{prop1}</div>
<div>{prop2}</div>
</div>
);
};
export default TestComponent;
Just change path to source folders:
const includePaths = [
path.resolve(__dirname, '../src'),
path.resolve(__dirname, '../test'),
path.resolve(__dirname, '../package.json'),
];
I had a similar issue after I decided to move webpack config into a config folder.
I assume that your folder structure might be:
-config/
|_webpack.config.js
-src/
|_/components/
|_index.ts
tsconfig.json
package.json
Just adjust values in includePaths variable depending on your folder structure.

"Parsing error: invalid character" when bundling images with Webpack's loaders

When I'm trying to bundle my React project, I get the following error regarding an image I'm about to load:
Oddly enough, when I hide the error overlay, I can see in a browser that my picture has been loaded correctly, despite Webpack's complaints. I've already been carefully following other working config examples, where that problem doesn't occur, but I can't easily identify the source of the issue, what leaves me here with no idea how to approach it or where to look for a hint. I've also tried different loaders: url-loader, file-loader and image-webpack-loader, but to no avail. Maybe that's Typescript what causes these troubles?
App.tsx where I'm importing my image:
import "./app.d";
import React from "react";
import SampleImage from "./assets/images/sample-image.jpg";
const App: React.FC = () => (
<div>
<img src={SampleImage} />
</div>
);
export default App;
app.d.ts with modules declarations to allow importing assets in typescripts files:
declare module "*.jpeg";
declare module "*.jpg";
declare module "*.jpeg";
declare module "*.png";
webpack.common.ts - my main Webpack config file, where I placed both url-loader and file-loader as it is in ejected create-react-app config, but it doesn't really change anything:
import path from "path";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import HtmlWebpackPlugin from "html-webpack-plugin";
import { CleanWebpackPlugin } from "clean-webpack-plugin";
module.exports = {
entry: path.resolve(__dirname, "..", "./src/index.tsx"),
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve("babel-loader"),
options: {
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
],
},
},
],
},
{
exclude: [
/\.html$/,
/\.(js|jsx)$/,
/\.(ts|tsx)$/,
/\.css$/,
/\.json$/,
/\.bmp$/,
/\.gif$/,
/\.jpe?g$/,
/\.png$/,
],
loader: require.resolve("file-loader"),
options: {
name: "static/media/[name].[hash:8].[ext]",
},
include: path.resolve(__dirname, "..", "./src/assets"),
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve("url-loader"),
options: {
name: "static/media/[name].[hash:8].[ext]",
},
include: path.resolve(__dirname, "..", "./src/assets"),
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js", ".jsx"],
},
output: {
path: path.resolve(__dirname, "..", "./dist"),
filename: "bundle.js",
},
devServer: {
contentBase: path.resolve(__dirname, "..", "./dist"),
hot: true,
compress: true,
open: true,
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: "React App",
template: path.resolve(__dirname, "..", "./src/index.html"),
}),
new ForkTsCheckerWebpackPlugin({
async: false,
eslint: {
files: path.resolve(__dirname, "..", "./src/**/*"),
},
}),
],
};
webpack.dev.ts
import webpack from "webpack";
import ReactRefreshWebpackPlugin from "#pmmmwh/react-refresh-webpack-plugin";
module.exports = {
mode: "development",
devtool: "eval-source-map",
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve("babel-loader"),
options: {
presets: [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript",
],
plugins: [require.resolve("react-refresh/babel")],
},
},
],
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ReactRefreshWebpackPlugin({
overlay: {
sockIntegration: "wds",
},
}),
],
};
webpack.prod.ts
import webpack from "webpack";
module.exports = {
mode: "production",
devtool: "source-map",
};
webpack.config.ts
import merge from "webpack-merge";
import devConfig = require("./webpack.dev");
import prodConfig = require("./webpack.prod");
import commonConfig = require("./webpack.common");
module.exports = ({ env }: { env: "dev" | "prod" }) => {
const envConfig = env === "dev" ? devConfig : prodConfig;
return merge(commonConfig, envConfig);
};
Additionaly, my .babelrc file:
{
"presets": [
"#babel/preset-env",
"#babel/preset-react",
"#babel/preset-typescript"
],
"plugins": [
"react-refresh/babel",
[
"#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
]
}
and tsconfig.json:
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
Scripts in package.json:
"scripts": {
"start": "webpack serve --config config/webpack.config.ts --env env=dev --hot",
"build": "webpack --config config/webpack.config.ts --env env=prod",
},
I'd be really grateful for any hint how to solve the issue.
Thanks to help received here: https://github.com/webpack/webpack/issues/12276#event-4152056913, I've managed to surpass the error overlay by changing the options passed to the ForkTsCheckerWebpackPlugin in my webpack.common.ts file.
Before:
new ForkTsCheckerWebpackPlugin({
async: false,
eslint: {
files: path.resolve(__dirname, "..", "./src/**/*"),
},
}),
Now:
new ForkTsCheckerWebpackPlugin({
async: false,
eslint: {
files: path.resolve(__dirname, "..", "./src/**/*.{ts,tsx,js,jsx}"),
},
}),

Webpack - import const from .d.ts file not working - Can't resolve '#nuvolo/servicenow-types/server/GlideRecord'

I'm doing this:
import { GlideRecord } from "#nuvolo/servicenow-types/server/GlideRecord";
I have a file node_modules/#nuvolo/servicenow-types/server/GlideRecord.d.ts
It contains:
...
type GlideRecordConstructor = { new <T>(table: string): GlideRecord<T> };
type GlideRecord<T> = GlideRecordBase<T> & T;
declare const GlideRecord: GlideRecordConstructor;
export { GlideRecord };
If I run tsc it works, no errors
Webpack says:
Module not found: Error: Can't resolve '#nuvolo/servicenow-types/server/GlideRecord' in ...
Webpack config:
{
mode: "production",
//set name of record as the library name
output: {
filename: "file.js"
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
//use: 'awesome-typescript-loader',
exclude: /node_modules/,
},
],
},
resolve: {
//modules: ['node_modules'],
extensions: [ '.ts', '.js' ], // Allows imports to work from .ts and .js
},
}
tsconfig.json:
{
"transpile": false,
"compilerOptions": {
"lib": ["es2015", "dom"],
"esModuleInterop": true,
"baseUrl": ".",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true
}
}
how do I fix this?
I've also created a GH issue here: https://github.com/nuvolo/sincronia/issues/138

webpack + typescript build aritifcate does not work

I have a typescript react project, with the following tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"downlevelIteration": true,
"experimentalDecorators": true,
"declaration": false,
"noUnusedLocals": false,
"removeComments": true,
"jsx": "react",
"types": [
"react"
],
"noImplicitAny": true,
"outDir": "./dist/",
"preserveConstEnums": true,
"sourceMap": true,
"typeRoots": [
"./types",
"node_modules/#types"
],
"strictNullChecks": true,
"baseUrl": "./",
},
"include": [
"src"
],
"exclude": [
"dist",
"node_modules"
]
}
when I do a dev run:
"webpack-dev-server --host 0.0.0.0 --port 3000 --hot --progress --colors --history-api-fallback --config webpack.dev.config.js"
It works fine, but if I do a prod build with the following webpack.prod.config.js file:
const webpack = require('webpack');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false')),
});
module.exports = {
mode: 'production',
entry: {
app: './src/index.tsx',
vendor: ['react', 'react-dom', 'react-router-dom', 'redux', 'react-redux', 'redux-thunk'],
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js',
},
target: 'web',
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx'],
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
loader: 'awesome-typescript-loader',
},
{
enforce: 'pre',
test: /\.js$/,
loader: 'source-map-loader',
},
{
test: /.svg$/,
use: ['#svgr/webpack'],
},
{
test: /\.css$/,
include: /app|node_modules/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.s[ac]ss$/i,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /.(jpg|png|gif|eot|woff|ttf|svg)/,
loader: 'file-loader',
},
],
},
plugins: [
new MiniCssExtractPlugin('[name].css'),
devFlagPlugin,
new webpack.ProvidePlugin({
React: 'react',
}),
],
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000,
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
terserOptions: {
ecma: 6,
},
}),
new OptimizeCSSAssetsPlugin({}),
],
},
};
It is also built successfully, but when I server the content and then go to localhost:80, the page failed to open, with following error in the console log:
TypeError: Object(...) is not a function
M index.es.js:382
React 11
<anonymous> index.tsx:36
Webpack 3
This problem cannot be reproduce with the dev build, so it seems the ts codes were okay, but the prod build didn't perform as expected. What did I miss in the webpack build setup?

Categories

Resources