React 的 Webpack 3 图像 src 问题(html-Loader & transform-react-jsx-img-import)

Webpack 3 image src issue for React ( html-Loader & transform-react-jsx-img-import )


U P D A T E D 存储库中的固定代码


首先我知道有一些关于这个主题的帖子,但它们太过时了(webpack 1 或 2)

我正在尝试为 React 图片设置一个 webpack 配置 避免丑陋的 var myImage = require('./imagePath/image.jpg');

仅当我通过 scss 或 css (背景图像即) 添加图像时它才有效,但如果我尝试在index.html 或在反应组件中它们不会生成。

我正在尝试使用 file-loaderhtml-loadertransform-反应-jsx-img-导入

我用示例案例创建了 this repository

您可以克隆它并通过 npm installyarn install

安装依赖项

过去 2 天我一直在为此苦苦挣扎,因此非常感谢您的帮助。

const autoprefixer      = require('autoprefixer'),
      DashboardPlugin   = require('webpack-dashboard/plugin'),
      ExtractTextPlugin = require('extract-text-webpack-plugin'),
      HtmlPlugin        = require('html-webpack-plugin'),
      path              = require('path'),
      webpack           = require('webpack');

const isProd = process.env.NODE_ENV === 'production';



//////////////////////// FILEPATH ///////////////////////
/////////////////////////////////////////////////////////

const buildFolder = 'dist';
const PATHS = {
  src       : path.resolve(__dirname, 'src'),
  build     : path.resolve(__dirname, buildFolder),
  appJS     : path.resolve(__dirname, 'src/app.js'),
  indexHTML : path.resolve(__dirname, 'src/index.html')
}



//////////////////////// PLUGINS ////////////////////////
/////////////////////////////////////////////////////////
const HtmlPluginOptions = {
  template: PATHS.indexHTML,
  minify: {
    collapseWhitespace: true
  },
  hash: true
};

const ExtractTextPluginOptions = {
  filename: '[name].bundle.css',
  disable: !isProd,
  allChunks: true,
  ignoreOrder: false
}

const devServerOptions = {
  contentBase: PATHS.build,
  compress: true,
  port: 6969,
  stats: 'errors-only',
  open: true,
  hot: true,
  openPage: ''
};

const pluginsDev = [
  new DashboardPlugin(),
  autoprefixer,
  new HtmlPlugin(HtmlPluginOptions),
  new ExtractTextPlugin(ExtractTextPluginOptions),
  new webpack.HotModuleReplacementPlugin()
];

const pluginsProd = [
  require('autoprefixer'),
  new HtmlPlugin(HtmlPluginOptions),
  new ExtractTextPlugin(ExtractTextPluginOptions)
];

var pluginsList = isProd ? pluginsProd : pluginsDev;



//////////////////////// LOADERS ////////////////////////
/////////////////////////////////////////////////////////
const postcss = {
  loader: 'postcss-loader',
  options: {
    sourceMap: 'inline',
    plugins() {
      return [autoprefixer({ browsers: 'last 3 versions' })];
    }
  }
};

const stylesDev  = ['style-loader', 'css-loader?sourceMap', postcss, 'sass-loader?sourceMap'];
const stylesProd = ExtractTextPlugin.extract({
  fallback: 'style-loader',
  use: ['css-loader', postcss, 'sass-loader'],
  publicPath: buildFolder
});

const styles = {
  test: /\.scss$/,
  use: isProd ? stylesProd : stylesDev
};

const javascript = {
  test: /\.(js|jsx)$/,
  use: 'babel-loader',
  exclude: /node_modules/
}

const images = {
  test: /\.(jpe?g|svg|png|gif)$/i,
  use: [
    'file-loader?name=assets/img/[name].[ext]'
  ]
}

const html = {
  test: /\.(html)$/,
  use: {
    loader: 'html-loader',
    options: {
      attrs: ['img:src', 'link:href']
    }
  }
}



//////////////////////// WEBPACK ////////////////////////
/////////////////////////////////////////////////////////
const webpackConfig = {
  entry: {
    app: PATHS.appJS
  },
  output:  {
    path: PATHS.build,
    filename: '[name].bundle.js'
  },
  module: {
    rules: [javascript, styles, images, html]
  },
  devServer: devServerOptions,
  plugins: pluginsList
}

module.exports = webpackConfig;

有一个 ./src/index.html 文件带有 <img> 标签 还有 ./src/components/App.js 文件和另一个 <img> 标签

再次感谢。请记住,您在 this repository 中有完整示例,请尝试显示两个徽标(webpack 和 React 徽标)

我在我的 webpack 3 配置中用来加载图像的是:

     {
        test: /\.(png|svg|jpg|webp)$/,
        use: {
          loader: 'file-loader',
        },
      },

我的 React 组件中的这段代码:

import logo from '../../img/logo.png';

...

<img className={style.logo} src={logo} alt="logo" />
/ 开头的

URL 不会被 html-loader 转换(参见 'Root-relative' URLs)。大多数加载器都遵循这种行为,因为这允许你使用现有的文件,这些文件使用服务器上的文件,而这些文件没有被 webpack 处理过。此外,如果它将 URL 解释为路径(就像在任何 JavaScript 模块中一样),它会在文件系统的根目录中查找,而这不是您想要的。

正如您在 SCSS 中所做的那样,您必须使用相对路径。

<img src="./public/assets/img/logo--webpack.svg" alt="Logo Webpack"/>

在 React 组件中,您不能使用 html-loader,因为您实际上不是在编写 HTML,而是 JSX,它是将转换为函数调用的语法糖。有关详细信息,请参阅 JSX In Depth

这意味着您必须导入图像并将其传递给 src 属性。

import reactLogo from '../public/assets/img/logo--react.svg';

<img src={reactLogo} alt="Logo React"/>

您或许可以使用 Babel 插件来转换 <img> 标签并自动添加源的导入。通过快速搜索,我找到了 babel-plugin-transform-react-jsx-img-import,虽然我不知道它是否有效,因为它似乎没有被维护。