We have a typescript react 'main' project. In the package.json is a dependency on another internal library that we use. The 'main' project builds fine when both projects targeted es5, but changing to es2017 throws the following error:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
It throws this error for all the files that declare enums in the dependent project.
This is the tsconfig.json file for the main project:
{
"compilerOptions": {
"resolveJsonModule": true,
"noImplicitAny": false,
"module": "commonjs",
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "es2017",
"jsx": "react",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"downlevelIteration": true,
"types": ["node", "jest"],
"baseUrl": "./src"
},
"exclude": ["node_modules"],
"includes": ["./src"]
}
And the webpack.config.js:
/* eslint no-use-before-define: 0 */
const path = require('path');
const webpack = require('webpack');
// plugins
const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const isProduction = process.env.NODE_ENV === 'production';
//entry --> output
module.exports = {
context: __dirname,
devtool: isProduction ? 'source-map' : 'eval-source-map',
entry: {
app: ['./src/index.tsx'],
},
output: {
path: path.join(__dirname, 'site'),
filename: '[name].[contenthash].js',
publicPath: '/',
},
devServer: {
inline: true,
hot: true,
historyApiFallback: true,
disableHostCheck: true,
},
resolve: {
extensions: ['.ts', '.js', '.jsx', '.tsx', '.pdf'],
alias: {
api: path.resolve('./src/api'),
assets: path.resolve('./src/assets'),
components: path.resolve('./src/components'),
context: path.resolve('./src/context'),
hooks: path.resolve('./src/hooks'),
models: path.resolve('./src/models'),
},
fallback: {
path: require.resolve('path-browserify'),
util: require.resolve('util'),
},
},
module: {
rules: [
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: isProduction ? [] : /(node_modules)/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
],
},
{
test: /\.(pdf)$/,
exclude: /(node_modules)/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
},
},
],
},
],
},
optimization: {
usedExports: isProduction ? true : false,
removeAvailableModules: isProduction ? true : false,
minimize: isProduction ? true : false,
minimizer: isProduction ? [new TerserPlugin()] : [],
splitChunks: {
chunks: 'all',
},
},
plugins: [
new ForkTsCheckerWebpackPlugin({
typescript: {
diagnosticOptions: {
semantic: true,
syntactic: true,
},
},
}),
new webpack.ProvidePlugin({
process: 'process/browser',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(
process.env.NODE_ENV || 'development',
),
'process.env.SENTRY_DSN': `"https://67422e5eff614bc2890330a8825d5c58@o348527.ingest.sentry.io/2686852"`,
'process.env.APP_VERSION': JSON.stringify(
process.env.npm_package_version,
),
}),
new HtmlWebpackPlugin({
template: 'htmlTemplates/index.wm.template',
inject: 'body',
title: 'TIPPEL',
}),
new CopyPlugin({
patterns: [
{
from: 'public/images',
to: 'images',
},
],
options: {
concurrency: 100,
},
}),
],
};
This is the babel.config.json:
{
"sourceType": "unambiguous",
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry",
"corejs": 3
}
],
"@babel/preset-typescript",
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
],
"@babel/plugin-proposal-class-properties",
["@babel/plugin-proposal-object-rest-spread", { "useBuiltIns": true }],
["@babel/plugin-transform-destructuring", { "useBuiltIns": true }],
["@babel/plugin-transform-object-assign", { "useBuiltIns": true }],
["@babel/plugin-transform-arrow-functions", { "useBuiltIns": true }]
]
}
From all I've read, nothing special is required to target es2017, so I am wondering what the solution is for this.
IMPORTANT UPDATE
If I change the package json to point to the local copy of the dependent repo (called 'models') then everything compiles.
eg this works:
in package.json: “@tplp/models”: “../models”
but this throws the loader build errors:
in package.json: “@tplp/models”:“2.6.3"
FOR REFERENCE
The same issue occurs with create-react-app if you try to use an npm package that has exports enums, you can read about it here.
For those interested, there are non-npm solutions to sharing typescript code between projects, such as this and this
2nd UPDATE The bable.config.json file has:
"@babel/preset-react"
which causes babel to "remove typescript types". Ref here. Not too sure exactly what they mean by that.
However removing that line (ie removing preset-react) means the build errors for the enums goes away...but of course now none of the JSX can compile.