web-dev-qa-db-fra.com

webpack incapable d'importer des images (avec express et angular2 dans TypeScript)

Je ne parviens pas à importer des images dans mon en-tête. Je suppose que c'est à cause de quelque chose que je ne fais pas bien lors de la compilation de ts (en utilisant webpack ts loader), car la même chose fonctionne avec reay (où les composants sont écrits en es6) 

L'emplacement de l'erreur est 

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

ma configuration webpack est 

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

et ma structure de répertoire ressemble à ceci

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

mon fichier tsconfig est comme suit:

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

Je soupçonne que je déconne quelque chose dans la compilation TypeScript, je ne sais pas quoi

19
Sahil Sharma

Le problème est que vous confondez les modules de niveau TypeScript et les modules de niveau Webpack.

Dans Webpack, tout fichier que vous importez passe par un pipeline de génération.

Dans TypeScript, seuls les fichiers .ts et .js sont pertinents et si vous essayez de import x from file.png, TypeScript ne sait simplement pas quoi en faire, Webpack config n'est pas utilisé par TypeScript.

Dans votre cas, vous devez séparer les problèmes, utiliser import from pour le code TypeScript/EcmaScript et utiliser require pour les spécificités Webpack.

Vous devez faire en sorte que TypeScript ignore cette syntaxe spéciale Webpack require avec une définition comme celle-ci dans un fichier .d.ts:

declare function require(string): string;

Cela fera en sorte que TypeScript ignore les instructions require et Webpack sera en mesure de le traiter dans le pipeline de génération.

36
bestander

Au lieu de:

import image from 'pathToImage/image.extension';

Utilisation:

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

J'utilise

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

et créé une définition TypeScript avec

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

Cela ne fonctionne que si vous avez le bon gestionnaire, tel que le chargeur de fichiers dans Webpack. Parce que ce gestionnaire vous donnera un chemin vers votre fichier.

9

J'ai aussi eu le même problème alors j'ai utilisé l'approche suivante:

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

Dans mon composant, j'ai simplement assigné l'image importée à un membre de données;

export class TempComponent{
    public tempImage = myImage;
}

et utilisé dans le template comme: 

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

Une petite amélioration à la réponse de Christian Stornowski serait de rendre le défaut d'exportation, c'est-à-dire 

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

Vous pouvez donc importer une image en utilisant:

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

Si vous souhaitez utiliser la syntaxe ES6 pour l'importation.

Tout d’abord, assurez-vous que dans votre tsconfig.json vous avez:

target: 'es5',
module: 'es6'

Ce qui suit devrait maintenant fonctionner:

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