webentwicklung-frage-antwort-db.com.de

webpack kann keine Bilder importieren (mit Express und angle2 in TypeScript)

Ich kann keine Bilder in meine headercomponent.ts importieren. Ich vermute, es liegt an etwas, das ich beim Kompilieren von ts falsch mache (unter Verwendung des webpack ts loader), weil dasselbe mit React funktioniert (wo die Komponenten in es6 geschrieben sind). 

Der Fehlerort ist 

//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">
      <a href="/"><img src="{{logoSource}}"></a>
    </div>

meine webpack config ist 

// 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'
};

und meine Verzeichnisstruktur sieht so aus

-/
 -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

meine tsconfig-Datei lautet wie folgt:

 //tsconfig.json
     {
      "compilerOptions": {
        "target": "es5",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
      },
      "exclude": [
        "node_modules"
      ]
    }

Ich vermute, ich versuche etwas in der TypeScript-Kompilierung

19
Sahil Sharma

Das Problem ist, dass Sie TypeScript-Module und Webpack-Module verwechseln.

In Webpack durchläuft jede importierte Datei eine Build-Pipeline.

In TypeScript sind nur .ts- und .js-Dateien relevant, und wenn Sie versuchen, import x from file.png TypeScript zu wissen, wissen Sie einfach nicht, was er damit tun soll.

In Ihrem Fall müssen Sie die Bedenken trennen, verwenden Sie import from für TypeScript/EcmaScript-Code und require für Webpack-Besonderheiten.

Sie müssen TypeScript dazu veranlassen, diese spezielle Webpack require-Syntax mit einer solchen Definition in einer .d.ts-Datei zu ignorieren:

declare function require(string): string;

Dadurch ignoriert TypeScript die Requirement-Anweisungen und Webpack kann es in der Build-Pipeline verarbeiten.

36
bestander

Anstatt:

import image from 'pathToImage/image.extension';

Benutzen:

const image = require('pathToImage/image.extension');
18
nadav

Ich benutze

import * as myImage from 'path/of/my/image.png';

und erstellt eine TypeScript-Definition mit

declare module "*.png" {
    const value: any;
    export = value;
}

Dies funktioniert nur, wenn Sie einen korrekten Handler wie den File-Loader im Webpack haben. Dieser Handler gibt Ihnen einen Pfad zu Ihrer Datei.

Ich hatte auch das gleiche Problem, also habe ich folgenden Ansatz verwendet:

import * as myImage from 'path/of/my/image';

In meiner Komponente habe ich das importierte Bild einfach einem Datenelement zugewiesen.

export class TempComponent{
    public tempImage = myImage;
}

und benutzte es in der Vorlage als: 

<img [src]="tempImage" alt="blah blah blah">
3
Hitesh Kumar

Eine kleine Verbesserung der Antwort von Christian Stornowski wäre der Export-Standard, d. H. 

declare module "*.png" {
  const value: string;
  export default value;
}

So können Sie ein Bild importieren mit:

import myImg from 'img/myImg.png';
3
Erik Vullings

Wenn Sie die ES6-Syntax zum Importieren verwenden möchten.

Stellen Sie zunächst sicher, dass Sie in Ihrem tsconfig.json Folgendes haben:

target: 'es5',
module: 'es6'

Folgendes sollte jetzt funktionieren:

import MyImage from './images/my-image.png';
0
Vedran

So können Sie den Standardimport verwenden:

import grumpyCat from '../assets/grumpy_cat.jpg';

Definiere jpg Moduldeklaration:

declare module "*.jpg" {
const value: string;
  export default value;
}

und in deinem tsconfig benutze "module": "es6" (siehe @vedran Kommentar oben ) oder wenn Sie "module": "commonjs" hinzufügen "esModuleInterop": true,

  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "esModuleInterop": true,
...

Quelle: https://github.com/TypeStrong/ts-loader/issues/344#issuecomment-381398818

0
Darkowic