使用Webpack和AngularJS图像GET在生产中引发404错误

时间:2019-01-11 15:32:41

标签: angularjs webpack path relative-path webpack-3

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

  

我无法在生产环境中加载静态图片;

     

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

版本

Webpack:3.12.0

文件加载器: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

这样,我就能使用 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/'output.publicPath: '/'中使用publicPath
  4. 使用文件加载器代替url加载器(当前保留)
  5. 将文件加载器与options: { useRelativePath: true }一起使用
  6. 将文件加载器与options: { publicPath: /customer_company_name/our_company_name/ }一起使用

请你能帮我吗?

4 个答案:

答案 0 :(得分:0)

我认为问题不在于替换模式,因为它适用于其他文件类型,但是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标签是否正确工作来测试是否是此原因。

答案 1 :(得分:0)

您可以尝试显式导入图像,而不是让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)}">`

答案 2 :(得分:0)

您可以尝试以下更改为index.html

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

答案 3 :(得分:0)

解决方案 让我们开始

output.publicPath: '/customer_company_name/our_company_name/'

这将按照here中所述正确地重写ng- / src路径。

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

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

随着我对webpack-dist.conf.js /整个项目的改进,我会更新这个答案。


没有给出答案的方法本身起作用,因此由于某些建议看起来合法,因此我将尝试将它们组合使用。

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