2016-03-22 10 views
14

Nie mogę importować obrazów do mojego pliku header.conf. Podejrzewam, że to dlatego, że coś robię źle podczas kompilacji ts (przy użyciu ładowacza WebPACK ts), ponieważ samo działa z reakcji (gdzie elementy są napisane w ES6)Nie można importować obrazów z komputera (używając express i angle2 w maszynopisie)

Lokalizacja błędu

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

mój WebPack config jest

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

i moja struktura katalogów wygląda tak

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

mój plik tsconfig jest następujący:

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

Podejrzewam jestem brudząc pewne rzeczy na maszynie kompilacji, nie wiem, co

+0

można importować, co chcesz w maszynopisie teraz, ale nie jest to całkowicie oczywiste. Zobacz ten numer, aby użyć '# deklarations.d.ts zadeklarować moduł '*'; # index.ts import * jako $ z 'jquery'; import * jako _ od 'lodash'; 'https://github.com/Microsoft/TypeScript/issues/2709 –

Odpowiedz

23

Problemem jest to, że mylić moduły poziomu maszynopis i moduły poziomu WebPACK.

W pakiecie Webpakowany dowolny importowany plik przechodzi przez niektóre kompilacje.

W plikach tylko pliki o numerach .ts i .js są istotne, a jeśli spróbujesz wpisać import x from file.png TypeScript nie wie, co z tym zrobić, konfiguracja Webpack nie jest używana przez TypeScript.

W twoim przypadku musisz rozdzielić obawy, użyj kodu import from dla kodu TypeScript/EcmaScript i użyj require dla specyfikacji Webpack.

Trzeba by zrobić maszynopis zignorować ten szczególny WebPACK require składni z definicji jak to w .d.ts pliku:

declare function require(string): string; 

To sprawi, maszynopis ignorować wymagać oświadczeń i WebPACK będzie w stanie przetworzyć go w budowa rurociągu.

+0

Dzięki, to rozwiązało obecny problem. Ale wciąż jest jeszcze wiele bitew do wygrania. Mam nadzieję, że to się poprawi, gdy kątowy 2 stanie się stabilny. Szkoda, że ​​nie było oficjalnych wytycznych dotyczących zestawu startowego/workflow. Wydaje się, że oni sami wciąż nie są pewni wielu rzeczy. –

+0

Nie jest to już całkowicie przypadek, możesz importować cokolwiek, co chcesz, teraz z użyciem 'declare module" * ";'. https://github.com/Microsoft/TypeScript/issues/2709 –

11

Zamiast:

import image from 'pathToImage/image.extension'; 

Zastosowanie:

const image = require('pathToImage/image.extension'); 
+1

to działało, powinno być poprawną odpowiedzią. Jednak dla mnie jest to jak czarna magia. Nie rozumiem, jak coś tak podstawowego powinno być tak nieintuicyjne. Skąd to wiedziałeś? –

+0

teraz nie wiem jak go używać. Jeśli go zapiszę, widzę adres URL, który otwiera obraz, który jest świetny, ale jeśli spróbuję użyć go jako źródła dla tagu "img", wydaje się do czytania go jako bardzo długi ciąg, który wygląda bardziej jak zawartość pliku obrazu (svg). Jest to bardzo mylące, ale dzięki za pomoc. –

+0

Najlepsze rozwiązanie zdecydowanie i moim zdaniem najlepsza praktyka i sposób postępowania, jeśli chodzi o czytelność i użyteczność. Nie musisz deklarować modułów ani hackować tsc lub webpacka. –

1

miałem również ten sam problem więc stosować następujące podejście:

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

W moim komponentu I po prostu przypisany importowanego obrazu do członka danych;

export class TempComponent{ 
    public tempImage = myImage; 
} 

i wykorzystał je w szablonie jako:

<img [src]="tempImage" alt="blah blah blah"> 
+0

Problem polega na tym, że podczas tworzenia produkcji każdy statyczny obraz powinien być dodany przyrostkiem 'md5'. Tak, twoja 'import * jak mojaImage z 'path/of/my/image'' jest uszkodzona. – novaline

5

Używam

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

i stworzył definicję maszynopis z

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

Zadziała tylko kiedy mieć poprawny moduł obsługi, taki jak plik -loader w pakiecie sieci Web. Ponieważ ten moduł obsługi da ci ścieżkę do twojego pliku.

+0

Kluczem dla mnie było stworzenie pliku definicji maszynopisu. Następnie Maszynopis zezwala na import. – miracle2k

+0

Problem polega na tym, że podczas tworzenia produkcji wszystkie statyczne obrazy powinny mieć przyrostek 'md5'. Tak, twoja 'import * jak mojaImage z 'path/of/my/image'' jest uszkodzona. Kolejny problem polega na tym, że niektóre obrazy o małym rozmiarze powinny być używane przez 'url base64',' url-loader' może konwertować obraz małego formatu na URL 'base64'.z "reaguj", wszystko działa dobrze. Ale 'angular2', wciąż szukam sposobu na rozwiązanie moich problemów. – novaline

1

Niewielka poprawa na odpowiedź Christiana Stornowski byłoby aby domyślną eksportowych, tj declare module "*.png" { const value: string; export default value; }

Więc można zaimportować obraz przy użyciu:

import myImg from 'img/myImg.png';

Powiązane problemy