Module parse failed: Unexpected character '#' even with shebang loader - npm

I am trying to use https://github.com/dipson88/treeselectjs in my polymer 3 application.
Though, when I try to import it in one of my js file like
import Treeselect from 'treeselectjs'
it throws the following error:
Module parse failed: Unexpected character '#' (1:2341) File was
processed with these loaders:
my webpack is :
const merge = require('webpack-merge');
const flowDefaults = require('./webpack.generated.js');
module.exports = merge(flowDefaults, {
mode: 'production',
module: {
rules: [
{
test: /\.svg$/,
use: {
loader: 'html-loader',
options: {
minimize: true
}
}
},
{
test: /\.mjs.js$/,
loader: 'string-replace-loader',
options: {
search: '#',
replace: '',
}
},
{
test: /\.js$/,
loader: ['shebang-loader','ify-loader']
}
]
},
stats: {
warnings: false
}
});
How can I resolve this

Related

Is Ionic+Vue as frontend combinable with Umbraco as backend? (Webpack frustrations)

My first question here on Stackoverflow :) I'm trying to make an app with Ionic&Vue, and as a CMS I'm using Umbraco. I want to connect the two, which I'm now trying by configuring Webpack, so that Webpack will take my main.ts file that Ionic&Vue created and do stuff with it and put it in the main Umbraco folder as a source file where I can reference Umbraco content.
I'm not having a lot of luck with it unfortunately. I've tried configuring a webpack.config.js file and installing a bunch of libraries like 'vue-loader', 'ts-loader', 'vue-template-compiler', 'vue-style-loader' et cetera. Some stuff is getting compiled, it's just that I keep getting an error that there's a mismatch in versions (vue is #3.0.2 and vue-template-compiler is #2.6.12). Ionic won't work with Vue under version 3 though so I feel like I'm stuck.
So my question: am I missing something? Is it really not possible or is there another way to compile a file from .ts to .js to a folder of my wish?
Edit (webpack config file):
var { HotModuleReplacementPlugin } = require('webpack');
var path = require('path');
var VueLoaderPlugin = require('vue-loader/lib/plugin');
var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = (env, argv) => {
let transpileOnly = argv.transpileOnly === 'true';
return {
entry: './src/main.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundledwebpack.js'
},
module: {
rules: [
{
test: /\.ts$/,
use: [
{
loader: "ts-loader",
}
]
},
{
// Now we apply rule for images
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
// Using file-loader for these files
loader: "file-loader",
// In options we can set different things like format
// and directory to save
options: {
outputPath: 'images'
}
}
]
},
{
// Apply rule for fonts files
test: /\.(woff|woff2|ttf|otf|eot)$/,
use: [
{
// Using file-loader too
loader: "file-loader",
options: {
outputPath: 'fonts'
}
}
]
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
'scss': [
'vue-style-loader',
'css-loader',
'sass-loader'
],
'sass': [
'vue-style-loader',
'css-loader',
'sass-loader?indentedSyntax'
]
},
compiler: '#vue/compiler-sfc'
}
}
]
},
plugins: [
new HotModuleReplacementPlugin(),
new VueLoaderPlugin(),
].concat(transpileOnly ? [
new ForkTsCheckerWebpackPlugin({
reportFiles: ['src/**/*.{ts,tsx,vue}', '!src/**/*.js.vue'],
tslint: true,
vue: true
})
] : [])
,
mode: 'development'
}
}
This sounds more like a vue issue than a Umbraco one. You should be able to do it. After a quick google there is a working project here:
https://github.com/ionic-team/ionic-vue-conference-app
Have you tried explicitly installing packages with version numbers that work, e.g.
npm install #ionic/vue#0.0.4

How to distinguish files which have the same name but in different sub-folders in sourcemap?

In my VUE project, there are several templates which have the same filename but located in different source sub-folders. I'm using webpack 3.12 to build it, and the devtool set to 'cheap-module-eval-source-map'.
After I run webpack-dev-server 2.11.1 to debug it, all template source files are put into the root folder 'webpack://' of the browser's sourcemap, so ONLY one of these files can exist, others are lost, I can't debug them.
Is there a way to make these files co-existing in the sourcemap?
module.exports = {
plugins: [
new VueLoaderPlugin()
],
context: path.resolve(__dirname, '../'),
entry: {
app: ['babel-polyfill', './src/main.js']
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production' ?
config.build.assetsPublicPath : config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'#': resolve('src'),
}
},
devtool: 'cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
},
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [{
from: /.*/,
to: path.posix.join(config.dev.assetsPublicPath, 'index.html')
}, ],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay ?
{
warnings: false,
errors: true
} :
false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
}
}
At last, I changed 'cheap-module-eval-source-map' to 'module-eval-source-map', the relative path of source files are kept.
I've read the official document of devtool, it says "it doesn't have column mappings, it only maps line numbers." if "cheap" mode used, I don't understand why the relative path is discarded.
eval-cheap-source-map - Similar to eval-source-map, each module is executed with eval(). It is "cheap" because it doesn't have column
mappings, it only maps line numbers. It ignores SourceMaps from
Loaders and only display transpiled code similar to the eval devtool.
eval-cheap-module-source-map - Similar to eval-cheap-source-map, however, in this case Source Maps from Loaders are processed for
better results. However Loader Source Maps are simplified to a single
mapping per line.
This worked for me when using vue-cli-service serve: https://github.com/vuejs/vue-cli/issues/2978#issuecomment-577364101
In vue.config.js:
let path = require('path')
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'development') {
// See available sourcemaps:
// https://webpack.js.org/configuration/devtool/#devtool
config.devtool = 'eval-source-map'
// console.log(`NOTICE: vue.config.js directive: ${config.devtool}`)
config.output.devtoolModuleFilenameTemplate = info => {
let resPath = path.normalize(info.resourcePath)
let isVue = resPath.match(/\.vue$/)
let isGenerated = info.allLoaders
let generated = `webpack-generated:///${resPath}?${info.hash}`
let vuesource = `vue-source:///${resPath}`
return isVue && isGenerated ? generated : vuesource
}
config.output.devtoolFallbackModuleFilenameTemplate =
'webpack:///[resource-path]?[hash]'
}
},
}

Integration of back-end webpack with Vue-CLI 3

I'm developing a full-stack application using Vue-CLI 3. The backend is written in TypeScript and so requires compilation etc. Currently I'm just using ts-node to run the backend app directly which works, but it would be much cleaner if I could also webpack the backend app to give a single server.js rather than multiple sprawling typescript files all over the place.
The problem is that the way I'd do this normally is have a single webpack.base.js and then include that in different webpack config files. I can't really do that because a lot of the webpack configuration is hidden away in vue-cli-service
Ended up pretty much having a base webpack config and extending client and server webpack configuration.
My app root webpack.config.js looks like this:
const { config: client } = require('./src/client/webpack.config');
const { config: server } = require('./src/server/webpack.config');
/**
* Webpack Build File
*
* This webpack configuration is used for only building the client and server
* bundles. It imports both of these from their respective directories, but
* allows for overrides if required.
*
* Other dev tools such as watching, hot module reloading etc. has been split
* out into other config files
*
* #param {object} env Webpack `env` object
*/
module.exports = ({ mode = 'development' } = {}) => ([
{
...client({ mode }, process.env),
},
{
...server({ mode }, process.env),
},
]);
My src/client/webpack.config.js looks like this:
const { resolve: _resolve, sep } = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackRootElementPlugin = require('html-webpack-root-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const { DefinePlugin } = require('webpack');
const paths = {
src: {
rootDir: _resolve(__dirname) + sep,
app: _resolve(__dirname, 'app') + sep,
},
dist: {
rootDir: _resolve(__dirname, '..', '..', 'dist'),
app: _resolve(__dirname, '..', '..', 'dist', 'public'),
},
};
/**
* Client webpack build configuration.
*
* This webpack config produces a bundle for the client-side application only.
*
* #param {object} webpackEnv Webpack env object (basically any/all options passed in via the CLI)
* #param {object} processEnv Process env object (environment variables from process.env)
*/
const config = ({ mode = 'none' }, { APP_NAME = '', BASE_URL = '/' } = {}) => ({
name: 'client',
target: 'web',
mode,
entry: {
app: paths.src.app + 'main.ts',
},
output: {
path: paths.dist.app,
},
optimization: {
runtimeChunk: 'single',
},
resolve: {
extensions: ['.ts', '.js', '.vue'],
plugins: [
new TSConfigPathsPlugin({
configFile: paths.src.rootDir + 'tsconfig.json',
}),
],
},
context: paths.src.rootDir,
module: {
rules: [
{
test: /\.tsx?$/,
include: paths.src.rootDir,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
happyPackMode: true,
},
},
],
},
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.s?[ac]ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
{
test: /\.(png|jpe?g|gif|svg|eot|ttf|woff|woff2)$/i,
loader: 'file-loader',
options: {
name: 'assets/[name].[hash].[ext]',
esModule: false,
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
favicon: paths.src.app + 'assets/logo.png',
title: APP_NAME,
}),
new HtmlWebpackRootElementPlugin('app'),
new VueLoaderPlugin(),
new DefinePlugin({
'process.env.BASE_URL': JSON.stringify(BASE_URL),
}),
],
});
module.exports = {
config,
paths,
};
and my src/server/webpack.config.js looks like this:
const { resolve: _resolve, sep } = require('path');
const TSConfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const nodeExternals = require('webpack-node-externals');
const { IgnorePlugin } = require('webpack');
const paths = {
src: _resolve(__dirname) + sep,
dist: _resolve(__dirname, '..', '..', 'dist'),
};
/**
* NestJs uses a custom wrapper around require() that allows it to show a
* warning when some extra package needs to be installed. This causes problems
* with webpack, so we're blacklisting packages we're not using with the
* IgnorePlugin below.
*
* To de-blacklist a package, just remove it from this array.
*/
const nestBlacklist = [
'^cache-manager$',
'^#nestjs/microservices$',
// packages below are required from microservices
'^amqp-connection-manager$',
'^amqplib$',
'^grpc$',
'^mqtt$',
'^nats$',
'^redis$',
];
/**
* Server webpack build configuration.
*
* This webpack config produces a bundle for the server-side application only.
*
* #param {object} webpackEnv Webpack env object (basically any/all options passed in via the CLI)
* #param {object} processEnv Process env object (environment variables from process.env)
*/
const config = ({ mode = 'none' }) => ({
name: 'server',
mode,
target: 'node',
entry: paths.src + 'main.ts',
externals: [nodeExternals()],
output: {
path: paths.dist,
filename: 'server.js',
},
resolve: {
extensions: ['.ts', '.js'],
plugins: [
new TSConfigPathsPlugin({
configFile: './tsconfig.build.json',
}),
],
},
context: paths.src,
optimization: {
minimize: false,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.ts$/,
include: paths.src,
exclude: /node_modules/,
use: [
{
loader: 'ts-loader',
options: {
happyPackMode: true,
},
},
],
},
],
},
plugins: [
new IgnorePlugin({
contextRegExp: /#nestjs/,
resourceRegExp: new RegExp(nestBlacklist.join('|')),
}),
],
node: {
__dirname: false,
},
});
module.exports = {
config,
paths,
};
This allows me to have distinct server and client side compilation configuration, but in such a way that's re-usable in other configurations. So, for webpack dev server - I have webpack.dev.config.js which contains the following:
const client = require('./src/client/webpack.config');
const server = require('./src/server/webpack.config');
const { HotModuleReplacementPlugin } = require('webpack');
const {
SERVER_PORT = 3000,
} = process.env;
/**
* Watch settings are the same between client and server, so we're keeping them
* here for consistency
*/
const watchConfig = {
watch: true,
watchOptions: {
ignored: /node_modules/,
},
};
/**
* Development Webpack Build File
*
* This webpack configuration extends `webpack.config.js` and builds on it to
* provide hot module replacement, watch moide and a dev server for the
* client-side code
*
* Other dev tools such as watching, hot module reloading etc. has been split
* out into other config files
*
* #param {object} env Webpack `env` object
*/
module.exports = ({ mode = 'development' } = {}) => ([
{
...client.config({ mode }, process.env),
...watchConfig,
devServer: {
contentBase: client.paths.dist.app,
historyApiFallback: {
rewrites: [
{ from: /./, to: '/index.html' },
],
},
port: 8000,
host: '0.0.0.0',
hot: true,
hotOnly: true,
proxy: {
'/api': `http://localhost:${SERVER_PORT}/`,
},
},
},
{
...server.config({ mode }, process.env),
...watchConfig,
plugins: [
...server.config({ mode }, process.env).plugins,
new HotModuleReplacementPlugin(),
],
},
]);
This config provides a setup that produces a server.js which then serves up a directory (in this case '/public'`) as it's static files dir.

building vuejs plugin with webpack

ERROR in ./src/Loader.vue
Module parse failed: C:\test\vuePlugin\src\Loader.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (1:0)
at Parser.pp$4.raise (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:2221:15)
at Parser.pp.unexpected (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:603:10)
at Parser.pp$3.parseExprAtom (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1822:12)
at Parser.pp$3.parseExprSubscripts (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1715:21)
at Parser.pp$3.parseMaybeUnary (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1692:19)
at Parser.pp$3.parseExprOps (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1637:21)
at Parser.pp$3.parseMaybeConditional (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1620:21)
at Parser.pp$3.parseMaybeAssign (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1597:21)
at Parser.pp$3.parseExpression (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:1573:21)
at Parser.pp$1.parseStatement (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:727:47)
at Parser.pp$1.parseTopLevel (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:638:25)
at Parser.parse (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:516:17)
at Object.parse (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\acorn\dist\acorn.js:3098:39)
at Parser.parse (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\lib\Parser.js:902:15)
at NormalModule. (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\lib\NormalModule.js:104:16)
at NormalModule.onModuleBuild (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\webpack-core\lib\NormalModuleMixin.js:310:10)
at nextLoader (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\webpack-core\lib\NormalModuleMixin.js:275:25)
at C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\webpack-core\lib\NormalModuleMixin.js:259:5
at Storage.finished (C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\enhanced-resolve\lib\CachedInputFileSystem.js:38:16)
at C:\Users\shubham-sharma2\AppData\Roaming\npm\node_modules\webpack\node_modules\graceful-fs\graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)
# multi main
"webpack --config --display-error-details ./webpack.config.js"
const webpack = require('webpack');
const merge = require('webpack-merge');
const path = require('path');
var config = {
entry:path.resolve(__dirname,'src/plugin.js'),
output: {
path: path.resolve( __dirname,'/dist/')
},
module: {
rules: [ {
test: /\.js$/,
loader: 'babel-loader',
include: __dirname,
exclude: /node_modules/
},
{
test: /\.vue$/,
loader: 'vue-loader'
} ]
},resolve: {
extensions: ['.vue', '.js', '.jsx','']
},plugins:[ new webpack.optimize.UglifyJsPlugin( {
minimize : true,
sourceMap : false,
mangle: true,
compress: {
warnings: false
}
} )]
};
config.node={
fs:'empty'
};
module.exports = [
merge(config, {
entry: path.resolve(__dirname,'src/plugin.js'),
output: {
filename: 'loader.min.js',
libraryTarget: 'window',
library: 'Loader',
}
}),
merge(config, {
entry: path.resolve(__dirname , 'src/Loader.vue'),
output: {
filename: 'loader.js',
libraryTarget: 'umd',
library: 'Loader',
umdNamedDefine: true
}
})
// Config 1: For browser environment
// merge(commonConfig, {
// }),
// Config 2: For Node-based development environments
// merge(commonConfig, {
// })
];
Add
const VueLoaderPlugin = require('vue-loader/lib/plugin')
to the top of your webpack config, and
new VueLoaderPlugin()
in your plugin section.
And for your style blocks, add:
// this will apply to both plain `.css` files
// AND `<style>` blocks in `.vue` files
{
test: /\.css$/,
use: [
'vue-style-loader',
'css-loader'
]
}
You might also try:
extensions: ['', '.vue', '.js', '.jsx']
I have seen the order become an issue.

webpack not able to import images( using express and angular2 in typescript)

I am not able to import images in my headercomponent.ts.
I suspect it is because of something i am doing wrong while compiling ts(using webpack ts loader) because same thing works with react( where the components are written in es6)
The error location is
//headercomponent.ts
import {Component, View} from "angular2/core";
import {ROUTER_DIRECTIVES, Router} from "angular2/router";
import {AuthService} from "../../services/auth/auth.service";
import logoSource from "../../images/logo.png"; //**THIS CAUSES ERROR** Cannot find module '../../images/logo.png'
#Component({
selector: 'my-header',
//templateUrl:'components/header/header.tmpl.html' ,
template: `<header class="main-header">
<div class="top-bar">
<div class="top-bar-title">
<img src="{{logoSource}}">
</div>
my webpack config is
// webpack.config.js
'use strict';
var path = require('path');
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var basePath = path.join(__dirname,'public');
//const TARGET = process.env.npm_lifecycle_event;
console.log("bp " + basePath)
module.exports = {
entry: path.join(basePath,'/components/boot/boot.ts'),
output: {
path: path.join(basePath,"..","/build"), // This is where images AND js will go
publicPath: path.join(basePath,"..","/build/assets"),
// publicPath: path.join(basePath ,'/images'), // This is used to generate URLs to e.g. images
filename: 'bundle.js'
},
plugins: [
new ExtractTextPlugin("bundle.css")
],
module: {
preLoaders: [ { test: /\.tsx$/, loader: "tslint" } ],
//
loaders: [
{ test: /\.(png!jpg)$/, loader: 'file-loader?name=/img/[name].[ext]' }, // inline base64 for <=8k images, direct URLs for the rest
{
test: /\.json/,
loader: 'json-loader',
},
{
test: /\.ts$/,
loader: 'ts-loader',
exclude: [/node_modules/]
},
{
test: /\.js$/,
loader: 'babel-loader'
},
{
test: /\.scss$/,
exclude: [/node_modules/],
loader: ExtractTextPlugin.extract("style", "css!postcss!sass?outputStyle=expanded")
},
// fonts and svg
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=application/octet-stream" },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=10000&mimetype=image/svg+xml" }
]
},
resolve: {
// now require('file') instead of require('file.coffee')
extensions: ['', '.ts', '.webpack.js', '.web.js', '.js', '.json', 'es6', 'png']
},
devtool: 'source-map'
};
and my directory structure looks like this
-/
-server/
-build/
-node-modules/
-public/
-components/
-boot/
-boot.component.ts
-header/
-header.component.ts
-images/
-logo.png
-services/
-typings/
-browser/
-main/
-browser.d.ts
-main.d.ts
-tsconfig.json
-typings.json
my tsconfig file is as follows:
//tsconfig.json
{
"compilerOptions": {
"target": "es5",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules"
]
}
I suspect I am messing some thing in typescript compilation , not sure what
The problem is that you confuse TypeScript level modules and Webpack level modules.
In Webpack any file that you import goes through some build pipeline.
In Typescript only .ts and .js files are relevant and if you try to import x from file.png TypeScript just does not know what to do with it, Webpack config is not used by TypeScript.
In your case you need to separate the concerns, use import from for TypeScript/EcmaScript code and use require for Webpack specifics.
You would need to make TypeScript ignore this special Webpack require syntax with a definition like this in a .d.ts file:
declare function require(string): string;
This will make TypeScript ignore the require statements and Webpack will be able to process it in the build pipeline.
Instead of:
import image from 'pathToImage/image.extension';
Use:
const image = require('pathToImage/image.extension');
I'm using
import * as myImage from 'path/of/my/image.png';
and created a typescript definition with
declare module "*.png" {
const value: any;
export = value;
}
This only works when you have a correct handler like the file-loader in webpack. Because this handler will give you a path to your file.
A small improvement to Christian Stornowski's answer would be to make the export default, i.e.
declare module "*.png" {
const value: string;
export default value;
}
So you can import an image using:
import myImg from 'img/myImg.png';
I also had same issue so I used following approach:
import * as myImage from 'path/of/my/image';
In my component I simply assigned the imported image to a data member;
export class TempComponent{
public tempImage = myImage;
}
and used it in template as:
<img [src]="tempImage" alt="blah blah blah">
If you want to use the ES6 syntax for importing.
First be sure that in your tsconfig.json you have:
target: 'es5',
module: 'es6'
The following should now work:
import MyImage from './images/my-image.png';
To be able to use default import like this:
import grumpyCat from '../assets/grumpy_cat.jpg';
Define jpg module declaration:
declare module "*.jpg" {
const value: string;
export default value;
}
and in your tsconfig use "module": "es6" (see #vedran comment above) or when you use "module": "commonjs" add "esModuleInterop": true,
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"esModuleInterop": true,
...
Source: https://github.com/TypeStrong/ts-loader/issues/344#issuecomment-381398818