如何使用Webpack处理动态图像路径

时间:2018-11-15 15:02:45

标签: javascript angularjs webpack

我已经设法在一个大型应用程序中处理了大部分图标,但是仍然有两个用例没有被抓住。

  • 角度模板中使用的动态路径
    <md-icon md-svg-src="{{'/assets/icons/ic-' + $ctrl.icon + '.svg'}}"></md-icon>

  • 在传递给角度模板的组件中用作变量的路径

即类似

class Comp {
   this.settingsLinks = [
     {name: 'advanced settings', icon: '/assets/icons/ic-settings.svg'}
   ]
}

然后在这样的模板中使用

<div ng-repeat="setting in $ctrl.settingsLinks">
  <md-icon md-svg-src="{{setting.icon}}"></md-icon>
</div>

我的webpack配置就像这样

module.exports = {
  module: {
    loaders: [
      {
        test: /\.html$/,
        loaders: 'html-loader',
        options: {
          attrs: ['md-icon:md-svg-src', 'img:ng-src'],
          root: path.resolve(__dirname, '../src'),
          name: '[name]-[hash].[ext]'
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'eslint-loader',
        enforce: 'pre'
      },
      {
        test: /\.(jpe?g|png|gif|svg)$/,
        loader: 'file-loader',
        options: {
          name() {
            return '[name]-[hash].[ext]';
          }
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loaders: [
          'ng-annotate-loader',
          'babel-loader'
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: conf.path.src('index.html')
    }),
    new ExtractTextPlugin('index-[contenthash].css'),
  ],
  output: {
    path: path.join(process.cwd(), conf.paths.dist),
    filename: '[name]-[hash].js'
  },
  entry: {
    app: [`./${conf.path.src('app/app.module.js')}`],
    vendor: Object.keys(pkg.dependencies)
  },
};

我一直在将webpack.ContextReplacementPlugin视为处理动态路径的一种潜在方法,是否有人对我要实现的目标有任何见识?我希望能够散列名称以清除缓存,但正在努力找出如何处理js和模板中的动态路径。

1 个答案:

答案 0 :(得分:0)

  

https://webpack.js.org/guides/dependency-management/

webpack允许访问require.context,该权限允许告诉webpack动态路径可能/应该是什么,它消除了所需内容的不确定性,并允许您从其原始名称中返回新的经过哈希处理的图标名称。如果我正确理解的话,它并不需要他们都承担进口费用,它只是在新旧名称之间建立了映射。

例如,这就是说抓取icons文件夹中的所有文件名,抓取以ic-开头的文件名,因为这是我们的图标命名方案,这会在构建时创建一个对象,我相信将使用所有可能的图标

const ICONS = require.context('../../../assets/icons', true, /ic-[a-zA-Z0-9.-]/);

返回的是一个函数,您可以在其中传递原始图标名称并获取哈希值。您还可以使用ICONS.keys()来获取图标数组。

这是我用来提供一些图标的示例用法。

const ICONS = require.context('../../../assets/icons', true, /ic-[a-zA-Z0-9.-]/);

export function getIconFromPath(path) {
  return ICONS(path);
}

function getIconsFromPaths(obj) {
  Object.keys(obj).forEach(key => Object.assign(obj, {[key]: ICONS(obj[key])}));
  return obj;
}

export default getIconsFromPaths({
  ARCHIVED: './ic-status-warning.svg',
  CANCELLED: './ic-status-cancelled.svg',
  CONFLICT: './ic-status-warning.svg',
  DRAFT: './ic-status-draft.svg',
  EARLIER: './ic-status-published.svg',
  ENDED: './ic-status-ended.svg',
  ERROR: './ic-status-published-failure.svg',
  FAILURE: './ic-status-failure.svg',
  INVALID: './ic-status-warning.svg',
  IN_PROGRESS: './ic-content-publish-in-progress.svg',
  LATEST: './ic-status-published-latest.svg',
  LOCKED: './ic-status-locked.svg',
  PUBLISHED: './ic-status-published.svg',
  PUBLISHING: './ic-content-publish-in-progress.svg',
  SCHEDULED: './ic-status-scheduled.svg',
  SCHEDULING: './ic-content-publish-in-progress.svg',
  UNLOCKED: './ic-status-unlocked.svg',
  UPDATED: './ic-webhook-request-success.svg',
  UNPUBLISHING: './ic-content-publish-in-progress.svg',
  UNSCHEDULING: './ic-content-publish-in-progress.svg',
  VALID: './ic-content-valid-tick.svg',
  WARNING: './ic-status-warning.svg'
});

因为webpack现在知道可以从此处返回什么内容,所以现在可以对名称进行哈希处理,并且您可以做各种各样的好事情,例如在构建时进行优化。

所以我的问题中给出的示例类将由

解决
import { getIconFromPath } from '../icons/;

class Comp {
   this.settingsLinks = [
     {
       name: 'advanced settings',
       icon: getIconFromPath('./ic-settings.svg')
     }
   ]
}