Изображения GET генерируют ошибку 404 при работе с использованием Webpack и AngularJS - PullRequest
0 голосов
/ 11 января 2019

У меня есть загадка, которую я не могу решить после многих попыток:

Я не могу загрузить статические изображения в производство;

во время разработки все в порядке ( npm run serve ), даже когда обслуживаются файлы из dist ( npm run serve: dist )

Версия

Webpack: 3.12.0

файл-загрузчик: 1.1.11

url-загрузчик: 1.1.2

AngularJS: 1.6,9

При разработке:

Мой index.html содержит эту строку, и веб-пакет не будет загружаться без

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

пока мой блок конфигурации AngularJS содержит

$locationProvider.hashPrefix('');

Я использую URL как 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. Использование publicPath в веб-пакете output.publicPath: '/customer_company_name/our_company_name/', а также output.publicPath: '/'
  4. Использование файлового загрузчика вместо url-загрузчика (в настоящее время это сохраняется)
  5. Использование загрузчика файлов с options: { useRelativePath: true }
  6. Использование загрузчика файлов с options: { publicPath: /customer_company_name/our_company_name/ }

Можете ли вы помочь мне, ребята, пожалуйста?

Ответы [ 4 ]

0 голосов
/ 21 января 2019

РЕШЕНИЕ Давайте начнем с

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/.

0 голосов
/ 20 января 2019

Вместо того чтобы позволить веб-пакету анализировать ваши шаблоны, вы можете попытаться явно импортировать ваши изображения и передать их в ваш шаблон.

Импортированные изображения будут затем обрабатываться с помощью настроенного image-loader или url-loader.

Статическое изображение

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

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

Динамическое изображение

Использование веб-пакета require.context

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

// In component declaration 
`<img ng-src="${pathToImages(dynamicImageName, true)}">`
0 голосов
/ 21 января 2019

Можете ли вы попробовать ниже изменить ваш index.html

<base href="./"></base>
0 голосов
/ 18 января 2019

Я думаю, что проблема не в шаблоне замены, так как он работает для других типов файлов, а в том, что webpack не знает, что делать с атрибутом ng-src. Я думаю, что он только смотрит на атрибут src img по умолчанию. Вы можете изменить его так, чтобы он распознал ng-src как:

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

альтернативный синтаксис:

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

Перед изменением вашей конфигурации вы можете просто проверить, является ли это причиной, проверив, работает ли замена в настоящее время правильно для тегов img с простой статической image.

...