[解決済み] webpackのファイルローダーで画像ファイルを読み込む方法
質問
を使っています。
ウェブパック
を管理するために
reactjs
プロジェクトに参加しています。webpackでjavascriptで画像を読み込みたい
file-loader
. 以下は
webpack.config.js
:
const webpack = require('webpack');
const path = require('path');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const PATHS = {
react: path.join(__dirname, 'node_modules/react/dist/react.min.js'),
app: path.join(__dirname, 'src'),
build: path.join(__dirname, './dist')
};
module.exports = {
entry: {
jsx: './app/index.jsx',
},
output: {
path: PATHS.build,
filename: 'app.bundle.js',
},
watch: true,
devtool: 'eval-source-map',
relativeUrls: true,
resolve: {
extensions: ['', '.js', '.jsx', '.css', '.less'],
modulesDirectories: ['node_modules'],
alias: {
normalize_css: __dirname + '/node_modules/normalize.css/normalize.css',
}
},
module: {
preLoaders: [
{
test: /\.js$/,
loader: "source-map-loader"
},
],
loaders: [
{
test: /\.html$/,
loader: 'file?name=[name].[ext]',
},
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets=es2015',
},
{test: /\.css$/, loader: 'style-loader!css-loader'},
{test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=/public/icons/[name].[ext]"},
{
test: /\.js$/,
exclude: /node_modules/,
loaders: ['babel-loader?presets=es2015']
}
]
},
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
},
output: {
comments: false,
},
}),
new NpmInstallPlugin({
save: true // --save
}),
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify("production")
}
}),
],
devServer: {
colors: true,
contentBase: __dirname,
historyApiFallback: true,
hot: true,
inline: true,
port: 9091,
progress: true,
stats: {
cached: false
}
}
}
この行で画像ファイルを読み込み、dist/public/iconsディレクトリにコピーし、ファイル名を同じにするようにしました。
{test: /\.(jpe?g|png|gif|svg)$/i, loader: "file-loader?name=/public/icons/[name].[ext]"}
しかし、使っていて2つの問題があります。私が
webpack
コマンドを実行すると、画像ファイルは
dist/public/icons/
ディレクトリに格納されます。しかし、distディレクトリにもこのファイル名でコピーされました。
もう一つの問題は、以下のコードを使ってこの画像ファイルを取り込みましたが、ブラウザに表示されないことです。imgタグのurl 'public/icons/imageview_item_normal.png' を使用すると、正常に動作します。画像ファイルからインポートしたオブジェクトを使用するにはどうすればよいですか?
import React, {Component} from 'react';
import {render} from 'react-dom';
import img from 'file!../../public/icons/imageview_item_normal.png'
export default class MainComponent extends Component {
render() {
return (
<div style={styles.container}>
download
<img src={img}/>
</div>
)
}
}
const styles = {
container: {
width: '100%',
height: '100%',
}
}
解決方法は?
問題点その1について
webpack.configでファイルローダーを設定すると、import/requireを使うたびにすべてのローダーに対してパスをテストし、マッチした場合はそのローダーを通してコンテンツを渡します。あなたの場合、次のようにマッチしました。
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "file-loader?name=/public/icons/[name].[ext]"
}
// For newer versions of Webpack it should be
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: 'file-loader',
options: {
name: '/public/icons/[name].[ext]'
}
}
に出力される画像が表示されます。
dist/public/icons/imageview_item_normal.png
というのは、望んだ動作です。
ハッシュファイル名も取得されるのは、インラインのファイルローダーを追加しているためです。あなたは画像を次のようにインポートしています。
'file!../../public/icons/imageview_item_normal.png'.
によるプリフィクス
file!
で、ファイルを再びファイルローダーに渡しますが、今度は名前の設定がありません。
だから、インポートは本当にそのままでいいんです。
import img from '../../public/icons/imageview_item_normal.png'
更新情報
cgatian さんの指摘の通り、実際に webpack のグローバル設定を無視してインラインのファイルローダーを使いたい場合は、import の前に感嘆符(!)を2つ付けるとよいでしょう。
import '!!file!../../public/icons/imageview_item_normal.png'.
問題点その2について
pngをインポートした後
img
変数は、ファイルローダーが知っているパスだけを保持します。
public/icons/[name].[ext]
(別名
"file-loader? name=/public/icons/[name].[ext]"
). あなたの出力ディレクトリ "dist"は不明です。
これを解決するには、2つの方法があります。
- すべてのコードを "dist" フォルダの下で実行します。
-
追加
publicPath
プロパティを出力設定に追加し、出力ディレクトリ (あなたの場合は ./dist) を指すようにします。
例
output: {
path: PATHS.build,
filename: 'app.bundle.js',
publicPath: PATHS.build
},
関連
-
[解決済み】React Js: Uncaught (in promise) SyntaxError: 位置 0 の JSON で予期しないトークン < が発生しました。
-
[解決済み】webpack: モジュールが見つかりません。Error: 解決できない(相対パスで)
-
[解決済み】Javascriptのコールバック関数がFirefoxで「Callback is not a function」というエラーを投げる
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み】未定義のプロパティ 'bind' を読み込めない。React.js【重複あり
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】Uncaught TypeError: 未定義のプロパティ 'msie' を読み取れない - jQuery tools
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptで要素のクラスを変更するにはどうすればよいですか?
-
[解決済み] jQueryでページを更新するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Facebook Graph API のクエリで with=location を使用すると "Uncaught (in promise) undefined" というエラーが発生する。
-
[解決済み】このエラーの原因は何ですか - "Fatal error: ローカルgruntを見つけることができません"
-
[解決済み】node.js TypeError: path must be absolute or specify root to res.sendFile [JSONのパースに失敗しました]。
-
[解決済み】Failed to load resource: net::ERR_FILE_NOT_FOUND loading json.js
-
[解決済み】SecurityError: オリジンを持つフレームがクロスオリジンフレームにアクセスするのをブロックした
-
[解決済み】jquery $.ajaxオブジェクトのresponseJSONプロパティを取得する方法 [重複]。
-
[解決済み】JavaScriptのgetElementByNameが機能しない
-
[解決済み】ある要素を別の要素に移動させるには?
-
[解決済み】React.jsの配列の子要素のユニークキーを理解する
-
[解決済み】XMLパースエラー:ルート要素が見つからない コンソールの場所 FF