I am trying to write both frontend (React) and backend (Express) in TypeScript. At the moment, my webpack.config.js in the root folder encounters an error even though I have ts-loader for it.
This is webpack.config.js
const webpack = require('webpack');
const path = require('path');
const config = {
cache: true,
mode: 'development',
entry: {
'user': ['./src/client/User/index.tsx', 'webpack-hot-middleware/client']
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/static'
},
devServer: {
contentBase: './dist',
hot: true
},
plugins: [new webpack.HotModuleReplacementPlugin()],
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
include: path.join(__dirname, 'client')
}
]
},
node: { fs: 'empty' }
};
module.exports = config;
And this is my tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"jsx": "react",
"esModuleInterop": true,
"outDir": "dist",
"sourceMap": true,
"baseUrl": "."
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
}
I got the error like this:
ERROR in ./src/client/User/index.tsx 10:1
Module parse failed: Unexpected token (10:1)
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
|
| const rootComponent = (
> <Provider store={store}>
| <BrowserRouter>
| <div id="page-container" className="sidebar-o sidebar-dark enable-page-overlay side-scroll page-header-fixed side-trans-enabled">
# multi ./src/client/User/index.tsx webpack-hot-middleware/client user[0]
Thanks to FunkeyFlo answer, I found out the answer myself. I have to change both:
tsconfig.json: include also src/**/*.tsx
webpack.config.js: entry to ./dist/src/client/User/index
change include section in tsconfig to the following
{
...
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
...
}
Related
when trying to run the lambda function I get the error "out/get-user-messages.handler is undefined or not exported". downloading the zip I see the "out" folder in the root and get-user-messages.js inside though. and I am exporting the handler
get-user-messages.ts
import "reflect-metadata";
import { APIGatewayEvent, APIGatewayEventRequestContext, APIGatewayProxyEvent } from "aws-lambda";
export const handler = async (event: APIGatewayProxyEvent, context: APIGatewayEventRequestContext) => {
/** Code **/
}
tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"module": "es2015",
"target": "esnext",
"noImplicitAny": false,
"outDir": "./out",
"strict": false,
"resolveJsonModule": true,
"strictNullChecks": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"esModuleInterop": true,
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts", "**/*.test.ts"],
"paths": {
"#/*": ["src/*"]
}
}
webpack.config.js
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
var path = require('path');
/** #type {import('webpack').Configuration} */
module.exports = {
mode: "production",
module: {
mode: "production",
rules: [
{
test: /\.js|.ts|.tsx/,
exclude: /node_modules/,
use: 'babel-loader'
},
],
},
resolve: {
extensions: ['*', '.js', '.jsx', '.tsx', '.ts', '.json'],
},
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: ["babel-loader"]
}
]
},
plugins: [new ForkTsCheckerWebpackPlugin()],
externals: ['aws-sdk'], //avoid un-needed modules since aws-sdk exists in aws lambdas already
entry: {
//list of compiled files
"get-user-messages": path.join(__dirname, "./src/lambda/get-user-messages.ts"),
"insert-user-message": path.join(__dirname, "./src/lambda/insert-user-message.ts"),
"mark-read-user-message": path.join(__dirname, "./src/lambda/mark-read-user-message.ts"),
"get-application-release-notes": path.join(__dirname, "./src/lambda/get-application-release-notes.ts"),
"insert-application-release-note": path.join(__dirname, "./src/lambda/insert-application-release-note.ts")
},
target: 'node',
output: {
path: path.join(__dirname, "./out"),
filename: "[name].js",
library: "[name]",
libraryTarget: 'commonjs'
}
};
.babelrc
{
"presets": [
["#babel/preset-env",{"targets":{"node":"14"}, "modules":false}],
"#babel/preset-typescript"
],
"sourceType": "unambiguous",
"plugins": [
"babel-plugin-transform-typescript-metadata",
["#babel/plugin-proposal-decorators", { "legacy": true }],
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-runtime"
]
}
the issue was the "library" option in the output section of webpack.config.js, removing that allowed me to successfully run the lambda function
I am trying to use imagemin node package in my project. It is a es6 module and I am getting error while using it.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. with "type" as "module" in package.json
ReferenceError: require is not defined with "type" as "commonjs" in package.json
My webpack config:
export default env => {
return {
mode: env.production ? 'production' : 'development',
entry: {
main: './src/main.ts',
worker: './src/worker.ts'
},
target: ['node', 'es2019'],
devtool: env.production ? false : 'inline-source-map',
watch: !env.production,
resolve: {
extensions: ['.ts', '.js'],
alias: {
src: _resolve(process.cwd(), './src')
}
},
module: {
rules: [{
test: /\.ts$/,
include: _resolve(process.cwd(), "src"),
use: 'ts-loader',
exclude: [/node_modules/, /\.spec\.ts/, /\.e2e-spec\.ts/]
}],
},
externalsPresets: { node: true },
externals: [nodeExternals()],
output: {
filename: '[name].js',
path: OUTPUT_DIR,
clean: !!env.production,
devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]',
library: {
type: 'module'
}
},
optimization: {
minimize: false, //!!env.production
mangleExports: true,
minimizer: [new terserPlugin({
terserOptions: {
output: {
comments: false
},
keep_classnames: true,
},
extractComments: false,
})]
},
experiments: {
outputModule: true
}
};
};
My tsconfig:
{
"compilerOptions": {
"module": "ES2020",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2019",
"sourceMap": true,
"strict": true,
"baseUrl": ".",
"esModuleInterop": true,
"noImplicitAny": true,
"moduleResolution": "node",
"outDir": "../bin/server",
"typeRoots": [
"node_module/#types",
"./typings"
],
"types": [
"node",
"#types/jest"
]
},
"exclude": [
"node_modules"
]
}
When I try to "import" imagemin in one of my .ts file, webpack convert it to "require". I have also tried using import() but it doesn't work either.
I have made a repo on github
Is there a way to get es6 bundle (preferred) or use imagemin with commonjs bundle?
I couldn't found a way to bundle es6 format through webpack but i was able to use es6 module in commonjs system while bundling through webpack.
externals: [
nodeExternals({
allowlist: ['imagemin', 'imagemin-mozjpeg']
}),
async function ({ request }) {
if (request === 'imagemin' || request === 'imagemin-mozjpeg')
return `import ${request}`;
},
]
This is how i got imagemin to work.
Change your start script
"start": "node --experimental-modules src/index.mjs "
and In package.json Add
{
...
"type": "module",
...
}
Here is webpack.config.ts
// const path = require("path");
import path from "path";
import HtmlWebpackPlugin from "html-webpack-plugin";
import CopyWebpackPlugin from "copy-webpack-plugin";
import webpack from "webpack";
import WebpackDevServer from "webpack-dev-server";
declare module "webpack" {
interface Configuration {
devServer?: WebpackDevServer.Configuration;
}
}
const config: webpack.Configuration = {
mode: "development",
target: "web",
entry: ["regenerator-runtime/runtime", "./src/index.tsx"],
output: {
filename: "bundle.js",
path: path.join(__dirname, "build"),
publicPath: "/",
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".css"],
alias: {
// add as many aliases as you like!
components: path.resolve(__dirname, "src/components"),
},
fallback: {
// path: require.resolve("path-browserify"),
fs: false,
assert: require.resolve("assert/"),
os: require.resolve("os-browserify/browser"),
constants: require.resolve("constants-browserify"),
},
},
devtool: "eval-cheap-source-map",
module: {
rules: [
{ test: /\.(ts|tsx)/, loader: "babel-loader", exclude: /node_modules/ },
{ test: /\.css$/, use: ["style-loader", "css-loader"] },
{
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[contenthash].[ext]",
outputPath: "fonts/",
},
},
],
},
{
test: /\.svg$/,
use: [
{
loader: "svg-url-loader",
options: {
limit: 10000,
},
},
],
},
],
},
devServer: {
contentBase: path.join(__dirname, "build"),
historyApiFallback: true,
overlay: true,
},
plugins: [
new HtmlWebpackPlugin({
title: "esBUild",
template: "src/index.html",
}),
new CopyWebpackPlugin({
patterns: [{ from: "assets", to: "assets" }],
}),
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
React: "react",
}),
],
};
export default config;
here is tsconfig.json:
{
"compilerOptions": {
// The standard typing to be included in the type checking process.
"lib": ["dom", "dom.iterable", "esnext"],
// Whether to allow JavaScript files to be compiled.
"allowJs": true,
//This allows default imports from modules with no default export in the type checking process.
"allowSyntheticDefaultImports": true,
// Whether to skip type checking of all the type declaration files (*.d.ts).
"skipLibCheck": true,
// This enables compatibility with Babel.
"esModuleInterop": true,
"strict": true,
// Ensures that the casing of referenced file names is consistent during the type checking process.
"forceConsistentCasingInFileNames": true,
// This allows modules to be in .json files which are useful for configuration files.
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"module": "es6",
"target": "es5",
"sourceMap": true,
"noEmit": true,
"jsx": "react",
"baseUrl": "src",
"paths": {
"components": ["components/*"]
}
},
"include": ["src"]
}
THis is the error I get :
import path from "path";
^^^^^^
SyntaxError: Cannot use import statement outside a module
I googled it and see some people suggest adding "type":"module", it did not work.
in tsconfig.json
"module": "es6" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
I tried each option but this did not work neither.
If I discard the typescript configuration, set up webpack with common.js, it works
Also .babelrc
{
"presets": [
"#babel/preset-react",
"#babel/preset-env",
"#babel/preset-typescript"
],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-object-rest-spread"
]
}
In my case I have to change to "module": "commonjs", inside tsconfig.json. Refer https://www.typescriptlang.org/tsconfig#module
In my case I have to install typescript types of plugins (vscode suggested it after restart the ide).
For example:
For dotenv-webpack package, I installed #types/dotenv-webpack.
Please refer to this section of the Webpack configuration documentation:
The above sample assumes version >= 2.7 or newer of TypeScript is used with the new esModuleInterop and allowSyntheticDefaultImports compiler options in your tsconfig.json file.
Note that you'll also need to check your tsconfig.json file. If the module in compilerOptions in tsconfig.json is commonjs, the setting is complete, else webpack will fail with an error. This occurs because ts-node does not support any module syntax other than commonjs.
There are three solutions to this issue:
Modify tsconfig.json.
Modify tsconfig.json and add settings for ts-node.
Install tsconfig-paths.
You've set the correct values for "esModuleInterop" and "allowSyntheticDefaultImports" in your tsconfig.json, so, to get rid of the error, you should do one of the above three options.
The first one suggests you to change the "module" compiler option's value to "commonjs".
The second one allows you to keep the "module" option's value as is, but you should add the settings for ts-node in your tsconfig.json.
The third one requires additional package installation and a separate TS configuration file.
I have a (node) server folder located in the root of my project, it is a Gatsby app written in Typescript
Here is one of the errors:
#27 27.94 ERROR in ./server/modules/version/index.ts
#27 27.94 Module not found: Error: Can't resolve '../../common/api/cache' in '/build/server/modules/version'
#27 27.94 # ./server/modules/version/index.ts 7:16-49
#27 27.94 # ./server/index.ts
The module it is referring to is this:
export class StatusCache {
private _cache: Record<string, CacheObject> = {};
private options: CacheOptions = {
expiresMinutes: 3
};
...
and the import in the other file is import { StatusCache } from "../../common/api/cache";
the folder structure of the area of interest:
server
- common
- api
- cache (StatusCache class location)
- modules
- <version>
- index.ts
and lastly my webpack.server.js
const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require("webpack");
const OUTPUT_FOLDER = "dist";
module.exports = env => ({
entry: "./server/index.ts",
mode: "production",
target: "node",
module: {
rules: [
{
test: /\.(tsx|ts)?$/,
use: [
{
loader: "ts-loader",
options: {
logInfoToStdOut: true,
logLevel: "info",
allowTsInNodeModules: false,
transpileOnly: true
}
}
],
exclude: /node_modules/
}
]
},
plugins: [
new CleanWebpackPlugin(),
new webpack.IgnorePlugin(/\.(test|spec)\./)
],
externals: {
bufferutil: "bufferutil",
"utf-8-validate": "utf-8-validate",
"mongodb-client-encryption": "mongodb-client-encryption"
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "server.js",
chunkFilename: "[name].bundle.js",
path: path.resolve(__dirname, OUTPUT_FOLDER),
publicPath: "/"
}
});
I found a solution that worked for me and might be useful for others.
I added and edited my tsconfig-server.json to this:
{
"compilerOptions": {
"baseUrl": "./server",
"module": "commonjs",
"esModuleInterop": true,
"target": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"noEmit": false
},
"lib": ["es2015"]
}
particularly the baseUrl, target, and moduleResolution
I had a similar Error , the problem was in gatsby-config,I had to add ignore property like so :
{
resolve: `gatsby-source-filesystem`,
options: {
name: `data`,
path: `${__dirname}/src/data/`,
ignore: [`**/\.*`], // ignore files starting with a dot
},
},
I want to build my graphql server app, when i build by webpack 4, i've got this error on a decorator of typeorm :
ERROR in ./src/models/user.ts 15:0
Module parse failed: Unexpected character '#' (15:0)
You may need an appropriate loader to handle this file type.
| import { JWT } from './jwt';
|
> #Entity()
| #Unique(['username'])
| #Unique(['email'])
# ./src/server.ts 15:0-37 34:45-49
The webpack.config.js is like this :
var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
var fs = require('fs');
var path = require('path');
var nodeExternals = require('webpack-node-externals');
module.exports = {
mode: 'production',
entry: './src/server.ts',
output: {
path: __dirname + '/dist',
filename: '[name].[chunkhash:8].js',
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
module: {
rules: [
{
test: '/\.tsx?$/',
exclude: '/node_modules/',
include: path.resolve(__dirname, 'src'),
use: {
loader: 'ts-loader',
options: {
transpileOnly: true
}
}
}
]
},
plugins: [
new ForkTsCheckerWebpackPlugin()
],
externals: [nodeExternals()],
};
The tsconfig.json is like this :
{
"exclude": [
"fixtures",
"tests"
],
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "dist",
"rootDir": "src",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"typeRoots": [
"node_modules/#types"
],
"lib": ["es2016", "esnext.asynciterable"]
}
}
When i compile with tsc, i've not got any error but i've got this error when i launch app by node dist/server.js :
(function (exports, require, module, __filename, __dirname) { import { Field, ID, Int, ObjectType } from 'type-graphql';
SyntaxError: Unexpected token {
Could you help me to resolve this bug ?
Thanks for advance
It looks like ts-loader isn't being used. I think that's because you've specified the test as a string instead of a regular expression. Try removing the surrounding single quotes. See the example in the documentation.