web-dev-qa-db-ja.com

webpackにバンドルされたnpmパッケージのアセットを含める

私はしばらくこれに頭をぶつけてきました、そしてそれが最初から可能でさえあるかどうか疑問に思っています。これで助けてくれてありがとう!

Npmパッケージ

基本的にReactコンポーネントのライブラリであるnpmパッケージがあります。このライブラリには、CSSのフォントや画像などのアセットを参照するスタイルシートが埋め込まれています。これらはすべてwebpackを使用してバンドルされます。 my-package.js

このための構成は次のようになります。

var path = require('path');

module.exports = {
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        loader: "style-loader!css-loader"
      },
      {
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$/,
        loader: 'file-loader'
      },
      {
        test: /\.styl$/,
        loader: 'style-loader!css-loader!stylus-loader'
      }
    ]
  },
  entry: [
    './lib/components/index.js',
    './lib/index.styl'
  ],
  output: {
    path: path.join(__dirname, 'build/'),
    filename: 'my-package.js'
  }
}

./lib/components/index.jsは次のようになります:

import '../index.styl';
import MyComponent from './my-component.js';

export {
  MyComponent
}

ここまでは順調ですね。

アプリケーション

別のコードベースに、このnpmパッケージをインストールするメインアプリケーションがあります。

私のアプリケーションルートにはこのパッケージが必要です...

import MyPackage from 'my-package';

そして、それ自体がWebpackにバンドルされ、ブラウザにロードされます。すべてのスクリプトとスタイルブロックは正しくバンドルされていますが、アセットを参照するスタイルはnpmパッケージ自体の相対URLを使用しているため、アプリケーションから404を取得します。

コンソールエラー

node_modules/my-package/build/[webpack-generated-name].jpgからこれらの画像を解決するようにwebpackに指示する方法はありますか?

私のアプリケーションのwebpack構成は次のようになります。

var path = require('path'),
    webpack = require('webpack');

module.exports = {
  devtool: '#eval-source-map',
  entry: [
    'my-package',
    'webpack/hot/only-dev-server',
    './app/index.js',
  ],
  output: {
    path: path.join(__dirname, 'build/static'),
    filename: 'bundled.js',
    publicPath: '/',
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],
  resolve: {
    extensions: ['', '.js']
  },
  resolveLoader: {
    'fallback': path.join(__dirname, 'node_modules')
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loaders: ['react-hot', 'babel'],
        exclude: /node_modules/,
        include: __dirname
      },
      {
        test: /\.css?$/,
        loader: "style-loader!css-loader",
        include: __dirname
      },
      {
        test: /\.(jpg|jpeg|ttf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
        loader: 'file-loader'
      },
      {
        test: /\.styl$/,
        loader: 'style-loader!css-loader!stylus-loader'
      }
    ]
  }
};
19

これを回避する方法を考え出しました。

アプリケーションのwebpack構成に、静的アセットを_node_module/my-package_からアプリサーバーのパブリックパスにコピーするプラグイン(@Interrobangが推奨)を追加しました。

_var TransferWebpackPlugin = require('transfer-webpack-plugin');

...
plugins: [
  new TransferWebpackPlugin([
    { from: 'node_modules/my-package/assets', to: path.join(__dirname, 'my/public') }
  ])
]
...
_

これらは、アセット名_localhost:XXXX/my-image.jpg_を呼び出すことでアクセスできるようになります。ここのサーバーは、正しく設定されている場合、基本的に_/my/public/my-image.jpg_を参照しています。

Expressを使用しているので、アプリサーバーでapp.use(express.static('my/public'))を定義する必要がありました。

9