简体   繁体   English

包括来自 webpack 捆绑的资产 npm package

[英]Include assets from webpack bundled npm package

I've been banging my head over this for a while, and am wondering if it's even possible to begin with.我一直在努力解决这个问题,我想知道它是否有可能开始。 Thanks for any help with this!感谢您对此的任何帮助!

The npm package npm package

I've got an npm package which is basically a library of React components.我有一个 npm package,它基本上是一个 React 组件库。 This library has embedded stylesheets, which references assets like fonts and images from the CSS.该库具有嵌入式样式表,其中引用了 fonts 等资产和来自 CSS 的图像。 These are then all bundled using webpack into my-package.js .然后这些都使用 webpack 捆绑到my-package.js中。

The config for this looks like:这个配置看起来像:

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

With ./lib/components/index.js looking like: ./lib/components/index.js看起来像:

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

export {
  MyComponent
}

So far, so good.到目前为止,一切都很好。

The application应用程序

Now in another code base I've got the main application, which install this npm package.现在在另一个代码库中,我得到了主应用程序,它安装了这个 npm package。

My application root requires this package...我的应用程序根需要这个 package...

import MyPackage from 'my-package';

And is then itself webpack bundled and loaded onto the browser.然后将其本身 webpack 捆绑并加载到浏览器上。 All the scripts and style blocks are bundled correctly, however the styles which reference the assets are using the relative url from the npm package itself, therefore giving me 404s from the application. All the scripts and style blocks are bundled correctly, however the styles which reference the assets are using the relative url from the npm package itself, therefore giving me 404s from the application.

console errs控制台错误

Is there any way to tell webpack to resolve these images from node_modules/my-package/build/[webpack-generated-name].jpg ?有没有办法告诉 webpack 从node_modules/my-package/build/[webpack-generated-name].jpg解析这些图像?

My application's webpack config looks like this:我的应用程序的 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'
      }
    ]
  }
};

Figured out a way around this. 找到了解决这个问题的方法。

In my application's webpack config I added a plugin (recommended by @Interrobang) which copies the static assets from the node_module/my-package into the app server's public path: 在我的应用程序的webpack配置中,我添加了一个插件(由@Interrobang推荐), node_module/my-package的静态资产复制到app服务器的公共路径中:

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

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

These will then be made accessible by calling the asset name: localhost:XXXX/my-image.jpg . 然后可以通过调用资产名称来访问它们: localhost:XXXX/my-image.jpg The server here is basically looking at /my/public/my-image.jpg if you've set it up correctly. 如果你正确设置它,这里的服务器基本上是在/my/public/my-image.jpg

I'm using Express, so I just had to define app.use(express.static('my/public')) in my app server. 我正在使用Express,所以我只需在app服务器中定义app.use(express.static('my/public'))

When bundling your NPM package, you could inline all the static assets into your final bundle.捆绑 NPM package 时,您可以将所有 static 资产内联到最终捆绑包中。 That way, your index.js that Webpack bundles for you would have all the static assets it needs, and simply importing that wherever you need your React components would do the trick.这样一来,您的index.js即 Webpack 捆绑包将拥有它需要的所有 static 资产,并且只需在您需要 React 组件的任何地方导入它们就可以了。

The best way to inline static assets as of Webpack 5 is by using the "asset/inline" module from Asset Modules, which you can read about here: https://webpack.js.org/guides/asset-modules/ The best way to inline static assets as of Webpack 5 is by using the "asset/inline" module from Asset Modules, which you can read about here: https://webpack.js.org/guides/asset-modules/

Simply put, your webpack.config.js should have a section as such:简单地说,您的webpack.config.js应该有这样的部分:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
 module: {
   rules: [
     {
       test: /\.(png|jpg|gif)$/i,
       type: 'asset/inline'
     }
   ]
 },
};

What really relates to your question here is the test for png, jpg, and gif files which uses the asset/inline module.与您的问题真正相关的是使用资产/内联模块的 png、jpg 和 gif 文件的测试。

The post here https://stackoverflow.com/a/73417058/14358290 explains it with slightly more detail. https://stackoverflow.com/a/73417058/14358290的帖子更详细地解释了它。

Other plugins that copy such files from your /node_modules to /build directory are hacky and create packages that are not really distributable - everyone else that uses the said package would have to set up their Webpack to do the same copying operation.将此类文件从/node_modules/build目录的其他插件是 hacky 并创建无法真正分发的包 - 使用上述 package 的其他所有人都必须设置他们的 Webpack 来执行相同的复制操作。 That approach can be avoided now that Webpack 5 solves this problem for us.现在可以避免这种方法,因为 Webpack 5 为我们解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM