"Unexpected token import" angular 2 external module - javascript

I'm using the ngx-magicsearch module in my project with. However, I get the following error:
Uncaught SyntaxError: Unexpected token import.
I am using the version of Angular 4.2.5, Webpack version 1.15.0 and Typescript 2.3.4
Here is my Webpack file:
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
'app': './app/app.module.ts',
'vendor': './app/vendor/vendor.ts'
},
resolve: {
extensions: ['', '.ts', '.js', '.css', '.html'],
modulesDirectories: ["node_modules", "assets\\js"]
},
output: {
filename: '[name].bundle.js',
},
module: {
noParse: [/jszip.js$/],
loaders: [{
test: /\.ts$/,
loaders: [
'awesome-typescript-loader',
'angular2-router-loader'
]
},
{
test: /\.html$/,
loader: 'html'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?.*$|$)/,
loader: 'file?name=assets/[name].[hash].[ext]'
},
{
test: /\.css$/,
exclude: './app',
loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
},
{
test: /\.css$/,
include: './app',
loader: 'raw'
},
{
test: /[\\\/]assets[\\\/]js[\\\/]modernizr\.min\.js$/,
loader: "imports?this=>window!exports?window.Modernizr"
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery",
KJUR: "jsrsasign-latest-all-min",
b64utoutf8: "base64x",
dateFormat: "dateformat",
moment: "moment"
}),
new ExtractTextPlugin('[name].bundle.css'),
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor']
})
],
devServer: {
historyApiFallback: true,
stats: 'minimal'
}
};
tsconfig.js:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noEmitHelpers": false,
"sourceMap": true,
"preserveConstEnums": true,
"alwaysStrict": true
},
"exclude": [
"node_modules"
],
"compileOnSave": false,
"buildOnSave": false
}
And the errors:

The entry point of ngx-magicsearch uses ES modules. You would need to transpile them with babel to use it. Usually the packages publish a transpiled version, although many of them now also publish a version with ES modules that can be used by bundling tools that support them. ES modules are supported out of the box, since webpack 2.
It is highly recommended to upgrade webpack. You'll have to adapt your config a little. For details have a look at the official migration guide.

Related

Absolute Imports not working with WebPack

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?

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}"),
},
}),

Issue with setup and run Electron + React + Typescript + Webpack application

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!

Cannot access prototype after compiling with Webpack in Typescritp

I Converted an old Javascript library for the company I work with, to a brand new Typescript Library. I use WebPack since I heard i need a module management system in order to make my library works in the browser. Problem is, whenever i'm trying to initiate my library ( in the JQuery function $(document).ready() , i cannot access my object prototype, I got a typeError :
Uncaught TypeError: Cannot read property 'loadPage' of undefined
Here is my code :
webpack.config.js
const path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
var webpack = require("webpack");
var fs = require("fs");
module.exports = {
entry: './src/libraryLoader.ts',
module: {
rules: [
{
test: /\.(tsx?)$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.json$/,
use: {
loader: "file-loader",
options: {
name: "[name].[ext]",
publicPath: "config/"
}
},
exclude: /node_modules/
}
]
},
plugins: [
new CopyWebpackPlugin([
{ from: 'src/settings/config', to: "config" }
]),
new UglifyJsPlugin({
uglifyOptions: {
ie8: true,
//compress: true
}
}),
new webpack.BannerPlugin({
banner: fs.readFileSync('./copyright', 'utf8'),
raw: true
})
],
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
modules: [
"node_modules"
]
},
// Enable sourcemaps for debugging webpack's output.
devtool: "eval",
output: {
filename: 'library.min.js',
path: path.resolve(__dirname, 'dist'),
},
watch: false,
watchOptions: {
ignored: /node_modules/
},
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery"
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"moduleResolution": "node",
"module": "commonjs",
"outDir": "build",
"strict": true,
"noImplicitAny": true,
"allowJs": true,
"sourceMap": true,
"typeRoots": [
"./node_modules/#types"
],
"project": "src",
"lib": [ "es2015", "dom"]
},
"include": [
"src/**/*",
"typings/**/*"
]
}
Where I load my library :
$(document).ready(function () {
let loader = new LibraryLoader();
loader.library().loadPage(); // <- Error here
/*...*/
});
My Loader class
export class LibraryLoader{
private _library: Library;
public LibraryLoader() {
this.setLibrary(new Library(/* ... unrelated options ... */));
}
public library(): Library{
return this._library;
}
private setLibrary(value: Library) : void {
this._library = value;
}
}
P.S. There is a loadPage function in the library, but the function library() return undefined anyways,

Categories

Resources