繁体   English   中英

图像GET使用Webpack和AngularJS在生产中抛出404错误

[英]Images GETs throw 404 error in production using Webpack and AngularJS

我有这个难题,经过多次尝试后无法解决:

我无法在生产中加载静态图像;

在开发( npm run serve )时一切都很好,即使从dist提供文件( npm run serve:dist

版本

Webpack:3.12.0

file-loader:1.1.11

url-loader:1.1.2

AngularJS:1.6.9

开发时:

我的index.html包含这一行,webpack将不会加载

<base href="/"></base>

而我的AngularJS配置块包含

$locationProvider.hashPrefix('');

我使用像http:// localhost:3000 /#/ appName / listingComponent / users这样的URL

我能够像这样使用ng-src (有时是动态绑定)来查看每个图像

<img ng-src="app/images/image1.png">

文件夹结构是这样的

ui/
├── conf/
│   ├── browsersync-dist.conf.js
│   ├── browsersync.conf.js
│   ├── gulp.conf.js
│   ├── webpack-dist.conf.js
│   └── webpack.conf.js
├── gulp_tasks/
│   ├── browsersync.js
│   ├── misc.js
│   └── webpack.js
├── node_modules/
├── src/
│   ├── app/
│   │   ├── config.js  //global variables
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── index.js
│   │   ├── index.less
│   │   ├── images/ <--
│   │   ├── actual_app_folders/
│   │   └── ...
├── gulpfile.js
└── package.json

在我的webpack-dist.js中,我有以下内容

module.exports = {
  module: {
    loaders: [
      {
        test: /\.json$/,
        loaders: [
          'json-loader'
        ]
      },
      {
        test: /\.js$/,
        exclude: [
          /node_modules/
        ],
        loader: 'babel-loader',
        options: {
          presets: ['es2015']
        }
      },
      {
        test: /\.js$/,
        exclude: [
          /node_modules/
        ],
        loaders: [
          'eslint-loader'
        ],
        enforce: 'pre'
      },
      {
        test: /\.(css|less)$/,
        exclude: '/node_modules/roboto-fontface/',
        loaders: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader?minimize!less-loader!postcss-loader'
        })
      },
      {
        test: /\.html$/,
        loaders: [
          'html-loader'
        ]
      },
      {
        test: /\.(jpe?g|png|gif|svg|eot|woff|ttf|svg|woff2)$/,
        loader: 'url-loader?name=[name].[ext]'
      }
    ]
  },
  plugins: [
    new webpack.NoEmitOnErrorsPlugin(),
    FailPlugin,
    new HtmlWebpackPlugin({
      template: conf.path.src('/app/index.html'),
      inject: true,
      chunksSortMode: 'dependency'
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: ['vendors', 'config'],
      minChunks: Infinity
    }),
    new ExtractTextPlugin('index-[contenthash].css'),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: () => [autoprefixer]
      }
    })
  ],
  output: {
    path: conf.paths.dist,
    filename: function(output) {
      return output['chunk']['name'] === 'config' ? '[name].js' : '[name]-[hash].js';
    },
    chunkFilename: '[name]-[hash].js'
  },
  entry: {
    app: `./${conf.path.src('/app/index')}`,
    config: `./${conf.path.src('/app/config')}`,
    vendors: Object.keys(pkg.dependencies).concat(['webpack-material-design-icons'])
  }
};

在生产中

构建过程将/customer_company_name/our_company_name/前缀添加到路径中,该路径变为

http://<customer_domain>:<domain_port>/customer_company_name/our_company_name/#/appName/listingComponent/users

而文件夹结构是这样的

our_company_name/
├── app/
│   ├── images/ <--
│   │   ├── image1.png
│   │   └── image2.png
├── app-<random_number>.js
├── config.js
├── favicon.ico
├── index.html
├── index-<random_number>.css
└── vendors.js

问题

现在,每次显示图片时,浏览器都会收到404错误

GET http://<customer_domain>:<domain_port>/app/images/image1.png 404 (Not Found)

而请求应该像这样

GET http://<customer_domain>:<domain_port>/customer_company_name/our_company_name/index.js

像应用程序中的每个其他文件一样。

我尝试了什么

到目前为止,以下没有任何帮助:

  1. 在以下<base href="/customer_company_name/our_company_name/"></base>构建过程时更改基本标记(目前保留)
  2. 明确要求图片与index.js中的每个其他文件一起使用require('./images/ODM_trasp48px.png'); (目前保留)
  3. 在webpack output.publicPath: '/customer_company_name/our_company_name/'使用publicPath output.publicPath: '/customer_company_name/our_company_name/'以及output.publicPath: '/'
  4. 使用文件加载器而不是url-loader(目前保留)
  5. 使用带有options: { useRelativePath: true }文件加载器options: { useRelativePath: true }
  6. 使用带有options: { publicPath: /customer_company_name/our_company_name/ }文件加载器options: { publicPath: /customer_company_name/our_company_name/ }

你能帮我小伙子们吗?

我认为问题不在于替换模式,因为它适用于其他文件类型,但事实上webpack不知道如何处理ng-src属性。 我认为它默认只查看img的src属性。 您可以将其更改为识别ng-src,如:

module.exports = {
  module: {
    loaders: [
    ...
    {
      test: /\.html$/,
      loaders: [ "html-loader?" + JSON.stringify({ attrs: ["img:src", "img:ng-src"] })]
    },
    ...
  ],
   ...

alt语法:

{
   test: /\.html$/,
   loaders: [ "html-loader?attrs=img:src img:ng-src" ]
}

在更改配置之前,您可以通过检查替换当前是否正常用于具有普通静态<img src =“...”/>的img标记来测试是否是这个原因。

您可以尝试显式导入图像并将其传递给模板,而不是让webpack解析模板。

然后,配置的image-loaderurl-loader将处理导入的图像。

静态图像

const myImage = require('./path/to/images/image1.png');

// In component declaration 
`<img ng-src="${myImage}">`

动态图像

使用webpack的require.context

const pathToImages = require.context('./path/to/images', true);
const dynamicImageName = 'foo.jpg',

// In component declaration 
`<img ng-src="${pathToImages(dynamicImageName, true)}">`

你可以尝试下面改变你的index.html

<base href="./"></base>

解决方案让我们开始吧

output.publicPath: '/customer_company_name/our_company_name/'

这将作为解释的正确利用改写NG-/ src目录路径护理在这里

我们不需要html-loader来解析ng- / src,唯一需要的是始终使用ng-src,否则构建将不会成功。

最终,不需要<base>标记,并且每个路径中的初始斜杠都不用于引用图像。

我将更新这个答案,因为我改进了webpack-dist.conf.js /整个项目。


没有给出答案,因此我会尝试将它们组合起来,因为一些建议看起来合法。

最后,如果我无法解决这个问题,我将尝试删除生产路径前缀/customer_company_name/our_company_name/

暂无
暂无

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

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