I've added a "common" package to our yarn (version 1) workspaces,
This package is storing a services files in TypeScript.
Other packages uses this package as follow (which works):
import {services} from 'common'
To transcript the files from TS to JS I've setup a Webpack (version 5) configuration with the following:
module.exports = {
entry: {
main: './src/index.ts',
service1: './src/services/service1.ts',
service2: './src/services/service2.ts',
},
devtool: 'inline-source-map',
module: {
rules: [{
test: /\.(ts|js)x?$/,
exclude: /(node_module|lib)/,
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
{
loader: 'ts-loader',
},
{
loader: '#stavalfi/babel-plugin-module-resolver-loader',
options: {
// all those options will go directly to babel-plugin-module-resolver plugin.
// Read babel-plugin-module-resolver DOCS to see all options:
// https://github.com/tleunen/babel-plugin-module-resolver/blob/master/DOCS.md
root: ['./src'],
extensions: ['.js', '.jsx', '.d.ts', '.ts', '.tsx'],
},
},
],
}, ],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: '[name].js',
path: resolve(__dirname, 'lib'),
},
mode: 'production'
}
I'm trying to export our services so it can be used as follow:
import service1 from 'common/services/service1'
I've tried editing the package.json with exports entry:
{
"name": "common",
"version": "1.0.0",
"license": "MIT",
"type": "commonjs",
"main": "lib/main.js",
"typings": "lib/index.d.ts",
"exports": {
".": "./lib/main.js",
"./services/service1": "./lib/services/service1.js"
},
"files": [
"lib"
],
"scripts": {
"build": "webpack"
}
...
tsconfig.json file:
"compilerOptions": {
"module": "commonJS",
"outDir": "./lib",
"declaration": true,
"declarationMap": true,
}
Although all this, I keep receiving the following errors:
Cannot find module 'common/services/service1' or its corresponding type declarations.
The files are present correctly in the lib files, but I'm not sure how else to handle this issue..
Any help will be highly appreciated!
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?
I'm trying to run my Electon application that I'm migrating from ES6 to Typescript. With my configuration I can build dll and main successfully but get an error (SyntaxError: Unexpected token ...) when I'm trying to run.
For now project files are mix of typescript and javascript files.
I use the following dependencies (main of them are):
"#babel/core": "^7.2.2", "#babel/register": "^7.0.0" and others #babel.
"electron": "6.0.2"
"react": "^16.9.0",
"typescript": "^3.5.3",
"webpack": "^4.39.2"
Scripts for run in package.json
"build": "concurrently \"npm run build-main\" \"npm run build-renderer\"",
"build-dll": "cross-env NODE_ENV=development node --trace-warnings -r #babel/register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.dev.dll.js --colors",
"build-e2e": "cross-env E2E_BUILD=true npm run build",
"build-main": "cross-env NODE_ENV=production node --trace-warnings -r #babel/register ./node_modules/webpack/bin/webpack --config webpack.config.main.prod.js --colors",
"build-renderer": "cross-env NODE_ENV=production node --trace-warnings -r #babel/register ./node_modules/webpack/bin/webpack --config webpack.config.renderer.prod.js --colors",
"electron-rebuild": "electron-rebuild --parallel --force --types prod,dev,optional --module-dir app",
"dev": "cross-env START_HOT=1 node -r #babel/register ./scripts/CheckPortInUse.js && cross-env START_HOT=1 npm run start-renderer-dev",
"start-main-dev": "cross-env HOT=1 NODE_ENV=development electron -r #babel/register ./app/main.dev.js",
"start-renderer-dev": "cross-env NODE_ENV=development node --trace-warnings -r #babel/register ./node_modules/webpack-dev-server/bin/webpack-dev-server --config webpack.config.renderer.dev.js",
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"outDir": "./dist",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"strictNullChecks": false,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"sourceMap": true,
"noImplicitAny": false,
"jsx": "react",
},
"include": [
"./app"
],
"exclude": [
"node_modules",
"**/node_modules/*",
"dist"
]
}
.babelrc
{
"presets": [
["#babel/preset-env", {
"targets": { "electron": "6.0.2" },
"corejs": "2",
"useBuiltIns": "usage"
}],
"#babel/preset-typescript",
"#babel/preset-react"
],
"plugins": [
// Stage 0
"#babel/plugin-proposal-function-bind",
// Stage 1
"#babel/plugin-proposal-export-default-from",
"#babel/plugin-proposal-logical-assignment-operators",
["#babel/plugin-proposal-optional-chaining", {
"loose": false
}],
["#babel/plugin-proposal-pipeline-operator", {
"proposal": "minimal"
}],
["#babel/plugin-proposal-nullish-coalescing-operator", {
"loose": false
}],
"#babel/plugin-proposal-do-expressions",
// Stage 2
["#babel/plugin-proposal-decorators", {
"legacy": true
}],
"#babel/plugin-proposal-function-sent",
"#babel/plugin-proposal-export-namespace-from",
"#babel/plugin-proposal-numeric-separator",
"#babel/plugin-proposal-throw-expressions",
// Stage 3
"#babel/plugin-syntax-dynamic-import",
"#babel/plugin-syntax-import-meta",
["#babel/plugin-proposal-class-properties", {
"loose": true
}],
"#babel/plugin-proposal-json-strings",
"#babel/plugin-proposal-object-rest-spread"
],
"env": {
"production": {
"plugins": [
"babel-plugin-dev-expression",
"#babel/plugin-transform-react-constant-elements",
"#babel/plugin-transform-react-inline-elements",
"babel-plugin-transform-react-remove-prop-types"
]
},
"development": {
"plugins": [
"#babel/plugin-syntax-typescript",
"react-hot-loader/babel"
]
}
}
}
webpack.config.base.js
import path from 'path';
import webpack from 'webpack';
import fs from 'fs';
import { dependencies as externals } from './app/package.json';
import { dependencies as possibleExternals } from './package.json';
export default {
externals: [
...Object.keys(externals || {}),
...Object.keys(possibleExternals ||{})
],
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
'ts-loader'
]
}
]
},
output: {
path: path.join(__dirname, 'app'),
// https://github.com/webpack/webpack/issues/1114
libraryTarget: 'commonjs2'
},
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
modules: [path.join(__dirname, 'app'), 'node_modules']
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
}),
new webpack.NamedModulesPlugin()
]
};
webpack.config.renderer.dev.dll.js
/**
* Builds the DLL for development electron renderer process
*/
import webpack from 'webpack';
import path from 'path';
import merge from 'webpack-merge';
import baseConfig from './webpack.config.base';
import { dependencies } from './package.json';
import CheckNodeEnv from './scripts/CheckNodeEnv';
CheckNodeEnv('development');
const dist = path.resolve(process.cwd(), 'dll');
export default merge.smart(baseConfig, {
devtool: 'eval',
mode: 'development',
target: 'electron-renderer',
externals: ['fsevents', 'crypto-browserify'],
module: require('./webpack.config.renderer.dev').default.module,
entry: {
renderer: Object.keys(dependencies || {}).filter(
dependency => dependency !== 'font-awesome'
)
},
output: {
library: 'renderer',
path: dist,
filename: '[name].dev.dll.js',
libraryTarget: 'var'
},
plugins: [
new webpack.DllPlugin({
path: path.join(dist, '[name].json'),
name: '[name]'
}),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development'
}),
new webpack.LoaderOptionsPlugin({
debug: true,
options: {
context: path.resolve(process.cwd(), 'app'),
output: {
path: path.resolve(process.cwd(), 'dll')
}
}
})
]
});
webpack.config.renderer.dev.js
import path from 'path';
import fs from 'fs';
import webpack from 'webpack';
import chalk from 'chalk';
import merge from 'webpack-merge';
import { spawn, execSync } from 'child_process';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import baseConfig from './webpack.config.base';
import CheckNodeEnv from './scripts/CheckNodeEnv';
CheckNodeEnv('development');
const port = process.env.PORT || 1212;
const publicPath = `http://localhost:${port}/dist`;
const dll = path.resolve(process.cwd(), 'dll');
const manifest = path.resolve(dll, 'renderer.json');
const requiredByDLLConfig = module.parent.filename.includes(
'webpack.config.renderer.dev.dll'
);
if (!requiredByDLLConfig && !(fs.existsSync(dll) && fs.existsSync(manifest))) {
execSync('npm run build-dll');
}
export default merge.smart(baseConfig, {
devtool: 'inline-source-map',
mode: 'development',
target: 'electron-renderer',
entry: [
'react-hot-loader/patch',
`webpack-dev-server/client?http://localhost:${port}/`,
'webpack/hot/only-dev-server',
path.join(__dirname, 'app/index.js')
],
output: {
publicPath: `http://localhost:${port}/dist/`,
filename: 'renderer.dev.js'
},
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
presets: [
'#babel/preset-env',
'#babel/preset-typescript',
'#babel/preset-react'
],
plugins: [
'#babel/plugin-transform-runtime',
["#babel/plugin-proposal-class-properties", { "loose": true }],
'react-hot-loader/babel'
]
}
}
},
{
test: /\.global\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /^((?!\.global).)*\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
}
]
},
// SASS support - compile all .global.scss files and pipe it to style.css
{
test: /\.global\.(scss|sass)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
sourceMap: true
}
},
{
loader: 'sass-loader'
}
]
},
// SASS support - compile all other .scss files and pipe it to style.css
{
test: /^((?!\.global).)*\.(scss|sass)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: true,
importLoaders: 1,
localIdentName: '[name]__[local]__[hash:base64:5]'
}
},
{
loader: 'sass-loader'
}
]
},
// WOFF Font
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// WOFF2 Font
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff'
}
}
},
// TTF Font
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/octet-stream'
}
}
},
// EOT Font
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: 'file-loader'
},
// SVG Font
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'image/svg+xml'
}
}
},
// Common Image Formats
{
test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/,
use: 'url-loader'
},
// All files with a ".ts" or ".tsx" extension will be handled by "awesome-typescript-loader".
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader"
},
// All output ".js" files will have any sourcemaps re-processed by "source-map-loader".
{
test: /\.js$/,
enforce: "pre",
loader: "source-map-loader" }
]
},
plugins: [
requiredByDLLConfig
? null
: new webpack.DllReferencePlugin({
context: process.cwd(),
// eslint-disable-next-line global-require
manifest: require(manifest),
sourceType: 'var'
}),
new webpack.HotModuleReplacementPlugin({
multiStep: true
}),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.EnvironmentPlugin({
NODE_ENV: 'development'
}),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new ExtractTextPlugin({
filename: '[name].css'
})
],
node: {
__dirname: false,
__filename: false
},
devServer: {
port,
publicPath,
compress: true,
noInfo: true,
stats: 'errors-only',
inline: true,
lazy: false,
hot: true,
headers: { 'Access-Control-Allow-Origin': '*' },
contentBase: path.join(__dirname, 'dist'),
watchOptions: {
aggregateTimeout: 300,
ignored: /node_modules/,
poll: 100
},
historyApiFallback: {
verbose: true,
disableDotRule: false
},
before() {
if (process.env.START_HOT) {
console.log('Starting Main Process...');
spawn('npm', ['run', 'start-main-dev'], {
shell: true,
env: process.env,
stdio: 'inherit'
})
.on('close', code => process.exit(code))
.on('error', spawnError => console.error(spawnError));
}
}
}
});
Error message:
SyntaxError: Unexpected token {
import { app, BrowserWindow } from 'electron';
^
at Module._compile (internal/modules/cjs/loader.js:722:23)
at Module._compile (C:\tool\node_modules\pirates\lib\index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:798:10)
at Object.newLoader [as .js] (C:\tool\node_modules\pirates\lib\index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:645:32)
at Function.Module._load (internal/modules/cjs/loader.js:560:12)
at loadApplicationPackage (C:\tool\node_modules\electron\dist\resources\default_app.asar\main.js:109:16)
at Object.<anonymous> (C:\tool\node_modules\electron\dist\resources\default_app.asar\main.js:155:9)
at Module._compile (internal/modules/cjs/loader.js:786:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:798:10)
Update:
As ford04 said, need to use commonjs or es2015, because electron is worked only with es2015 standard. Need to set up babel presets/plugins either in .babelrc file or webpack config as well.
tsconfig.js
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"es2015",
"es6",
],
"outDir": "./dist",
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"strictNullChecks": false,
"forceConsistentCasingInFileNames": true,
"module": "es2015",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"sourceMap": true,
"noImplicitAny": false,
"jsx": "react"
},
"include": [
"./app"
],
"exclude": [
"node_modules",
"**/node_modules/*",
"dist"
]
}
.babelrc I've replaced with babel.config.js according to electron-typescript
const developmentEnvironments = ['development', 'test'];
const developmentPlugins = [
require('react-hot-loader/babel'),
require('#babel/plugin-syntax-typescript')
];
const productionPlugins = [
require('babel-plugin-dev-expression'),
// babel-preset-react-optimize
require('#babel/plugin-transform-react-constant-elements'),
require('#babel/plugin-transform-react-inline-elements'),
require('babel-plugin-transform-react-remove-prop-types')
];
module.exports = api => {
const development = api.env(developmentEnvironments);
return {
presets: [
[
require('#babel/preset-env'),
{
targets: { electron: require('electron/package.json').version },
useBuiltIns: 'usage',
corejs: 2
}
],
require('#babel/preset-typescript'),
[require('#babel/preset-react'), { development }]
],
plugins: [
// Stage 0
require('#babel/plugin-proposal-function-bind'),
// Stage 1
require('#babel/plugin-proposal-export-default-from'),
require('#babel/plugin-proposal-logical-assignment-operators'),
[require('#babel/plugin-proposal-optional-chaining'), { loose: false }],
[
require('#babel/plugin-proposal-pipeline-operator'),
{ proposal: 'minimal' }
],
[
require('#babel/plugin-proposal-nullish-coalescing-operator'),
{ loose: false }
],
require('#babel/plugin-proposal-do-expressions'),
// Stage 2
[require('#babel/plugin-proposal-decorators'), { legacy: true }],
require('#babel/plugin-proposal-function-sent'),
require('#babel/plugin-proposal-export-namespace-from'),
require('#babel/plugin-proposal-numeric-separator'),
require('#babel/plugin-proposal-throw-expressions'),
// Stage 3
require('#babel/plugin-syntax-dynamic-import'),
require('#babel/plugin-syntax-import-meta'),
[require('#babel/plugin-proposal-class-properties'), { loose: true }],
require('#babel/plugin-proposal-json-strings'),
require('#babel/plugin-transform-runtime'),
...(development ? developmentPlugins : productionPlugins)
]
};
};
webpack.config.base.js
import path from 'path';
import webpack from 'webpack';
import fs from 'fs';
import { dependencies as externals } from './app/package.json';
export default {
externals: [
...Object.keys(externals || {})
],
module: {
rules: [
{
test: /\.(js|jsx|tsx|ts)$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
'ts-loader'
]
}
]
},
output: {
path: path.join(__dirname, 'app'),
libraryTarget: 'commonjs2'
},
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
modules: [path.join(__dirname, 'app'), 'node_modules']
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
}),
new webpack.NamedModulesPlugin()
]
};
Your error indicates that your build system somehow did not transpile ES modules syntax to CommonJS syntax. Electron does not support ES modules in a native way easily (some good links summarizing this: Link, Link, Link, Link), so it cannot interpret the import statement at runtime.
Your old .js files with ES modules seem to be the crux here, as you transpile .ts files to "target": "es5" according to tsconfig.json. In .babelrc, you configured #babel/preset-env like this:
[
"#babel/preset-env", {
"targets": { "electron": "6.0.2" },
"corejs": "2",
"useBuiltIns": "usage"
}
]
My guess is there is no transpilation to CommonJS, because you specified Electron 6.0.2 as target, which maps to a very decent Chromium version supporting ES modules - see the setting modules: auto and what it means for further infos.
I would further isolate your problem to the main process, as you set custom Babel settings for renderer:
webpack.config.renderer.dev.js, babel-loader:
use: {
loader: 'babel-loader',
options: {
...
}
}
Whenever you set these options, .babelrc will be completely ignored and everything from options taken during the webpack build including babel transformations. So for the renderer config, Babel should take its default options, which includes converting to CommonJS syntax, effectively eliminating import errors in the renderer process.
Solution
We have to bring Babel to transpile your main process .js files to CommonJS syntax. Easiest way is to change modules option:
[
"#babel/env", {
...
"modules": "cjs"
}
],
You could add this setting in a babel config for your main process or directly in the options of babel-loader in your main webpack config (similar to renderer webpack.config). Remember, if you do the latter, you have to add every setting from .babelrc in options. As an alternative to modules option, you could also try the #babel/plugin-transform-modules-commonjs plugin.
Puh, that was a bit longer than expected. Hope you are still awake and that it helps out. Good luck!
I have a problem at import json dynamically using webpack.
(https://webpack.js.org/api/module-methods/#import-)
It keep shows this error - TS2307: Cannot find module
package versions are..
webpack version: 2.7.0
typescript version: 2.4.2
awesome-typescript-loader: 3.2.1
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"noImplicitAny": true,
"module": "esnext",
"moduleResolution": "node",
"target": "es6",
"jsx": "react",
"allowJs": true,
"allowSyntheticDefaultImports": true
},
"awesomeTypescriptLoaderOptions": {
"useBabel": true,
"useCache": true
},
"exclude": ["node_modules"],
"include": [
"./components/**/*",
"./core/*",
"./pages/*",
"./utils/*",
"./urls/*",
"./translations/**/*",
"./main.tsx"
]
}
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const AssetsPlugin = require('assets-webpack-plugin');
const pkg = require('./package.json');
const isDebug = global.DEBUG === false ? false : !process.argv.includes('--release');
const isVerbose = process.argv.includes('--verbose') || process.argv.includes('-v');
const useHMR = !!global.HMR; // Hot Module Replacement (HMR)
const babelConfig = Object.assign({}, pkg.babel, {
babelrc: false,
cacheDirectory: useHMR,
});
// Webpack configuration (main.js => public/dist/main.{hash}.js)
// http://webpack.github.io/docs/configuration.html
const config = {
// The base directory for resolving the entry option
context: __dirname,
// The entry point for the bundle
entry: [
// require('babel-polyfill'),
'./main.tsx'
],
// Options affecting the output of the compilation
output: {
path: path.resolve(__dirname, './public/dist'),
publicPath: '/dist/',
filename: isDebug ? '[name].js?[hash]' : '[name].[hash].js',
chunkFilename: isDebug ? '[id].js?[chunkhash]' : '[id].[chunkhash].js',
sourcePrefix: ' ',
},
// Developer tool to enhance debugging, source maps
// http://webpack.github.io/docs/configuration.html#devtool
devtool: isDebug ? 'inline-source-map' : false,
// What information should be printed to the console
stats: {
colors: true,
reasons: isDebug,
hash: isVerbose,
version: isVerbose,
timings: true,
chunks: isVerbose,
chunkModules: isVerbose,
cached: isVerbose,
cachedAssets: isVerbose,
},
// The list of plugins for Webpack compiler
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
__DEV__: isDebug,
}),
// Emit a JSON file with assets paths
// https://github.com/sporto/assets-webpack-plugin#options
new AssetsPlugin({
path: path.resolve(__dirname, './public/dist'),
filename: 'assets.json',
prettyPrint: true,
}),
],
// Options affecting the normal modules
module: {
rules: [
{
test: /\.tsx?$/,
include: [
path.resolve(__dirname, './components'),
path.resolve(__dirname, './core'),
path.resolve(__dirname, './pages'),
path.resolve(__dirname, './apis'),
path.resolve(__dirname, './urls'),
path.resolve(__dirname, './translations'),
path.resolve(__dirname, './main')
],
loader: 'awesome-typescript-loader'
},
{
test: /\.css/,
use: [{loader: 'style-loader'}, {loader: 'css-loader', options:
{
sourceMap: isDebug,
// CSS Modules https://github.com/css-modules/css-modules
modules: true,
localIdentName: isDebug ? '[name]_[local]_[hash:base64:3]' : '[hash:base64:4]',
// CSS Nano http://cssnano.co/options/
minimize: !isDebug,
}},
// {loader: 'postcss-loader'}
],
},
{
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000',
},
{
test: /\.(eot|ttf|wav|mp3)$/,
loader: 'file-loader',
},
],
},
externals: {
react: 'React'
},
resolve: {
extensions: ['.js', '.ts', '.tsx']
}
};
// Optimize the bundle in release (production) mode
if (!isDebug) {
config.plugins.push(new webpack.optimize.UglifyJsPlugin({ compress: { warnings: isVerbose }, sourceMap: isDebug }));
config.plugins.push(new webpack.optimize.AggressiveMergingPlugin());
}
// Hot Module Replacement (HMR) + React Hot Reload
if (isDebug && useHMR) {
babelConfig.plugins.unshift('react-hot-loader/babel');
config.entry.unshift('react-hot-loader/patch', 'webpack-hot-middleware/client');
config.plugins.push(new webpack.HotModuleReplacementPlugin());
config.plugins.push(new webpack.NoEmitOnErrorsPlugin());
}
module.exports = config;
custom.d.ts
declare module "*.json" {
const value: any;
export default value;
}
my error code
// TS2307: Cannot find module './test.json'.
import('./test.json').then(_ => {
console.log(_
})
// but these codes work
import './test.json'
import('./test.js').then(_ => { console.log(_)})
I have searched issues as much as possible I can. but no one seems to encountered this issue.
Here's related links what I found.
https://github.com/Microsoft/TypeScript/issues/16820
https://blog.josequinto.com/2017/06/29/dynamic-import-expressions-and-webpack-code-splitting-integration-with-typescript-2-4/
If anyone have a clue, please let me know.
Are you sure your custom.d.ts is in a folder included in the compilation? I believe only typings in packages under node_modules/#types are included if they are not in the "files" or "include" properties in tsconfig.json.