Aurelia,webpack和动态参考图像

时间:2018-04-23 22:22:56

标签: webpack aurelia asp.net-core-2.0

假设我们有这样的标记(多个tbody,我知道)。

<tbody repeat.for="order of orders">
  <tr repeat.for="line of order.lines">
    <td>
      <img if.bind="order.urgent === 'T'" src="../app/alert.svg">
      <img if.bind="line.outOfSquare" src="../app/oos.svg">
    </td>
    <td class="min-width">
      <img src.bind="'../app/'+line.type+'.svg'" alt="${line.type}">
    </td>
  </tr>
</tbody>

dotnet new Aurelia创建的默认项目中,图像内嵌为DataUrls,因为它们很小。这是合理的,但根据绑定数据,它们在许多行中重复。调整webpack.config.js将阈值降低到1024字节,我们有

{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=1024' }

现在,图像在wwwroot / dist中显示为带有散列名称,并且URL被重写。计算的URL目标也通过添加到webpack.config.js

捆绑在一起
  ,new GlobDependenciesPlugin({
    "boot": [
      "ClientApp/app/components/**/*.svg"
    ]
  })

不幸的是,计算的网址不会被重写。

src.bind="'../app/'+line.type+'.svg'"

他们现在已经破产了。

如何在运行时解析应用程序相对路径?

我们需要在运行时解决这个问题,但到目前为止我找不到任何支持。已经提出了各种可能性:

  • 完全禁止处理图像并使用构建任务打包它们
  • 使用require在运行时转换网址
  • 使用带有静态URL的imgs的隐藏div和原始URL作为id值,然后使用它们在运行时进行映射。

我自己的研究表明有一些webpack插件以json的形式发出这些映射,但是我对Aurelia构建过程的浅薄理解不允许我利用它 - 除了我不知道的其他任何东西导致此输出可供应用程序使用。

这似乎相关但无知阻碍了我。 How to load image files with webpack file-loader

我尝试使用require不起作用,但我怀疑Aurelia模块中自动在范围内的require方法不是可能解决映射的Webpack要求。据推测,webpack可以在运行时加载和解码打包的应用程序,但我真的不知道,因为到目前为止它刚刚起作用,让我能够在幸福的无知中运作。

我知道我可以通过使用对资源的静态引用分别处理每个行类型来将其嵌入到页面中,如下所示:

<img if.bind="line.type === 'AL'" src="../app/al.svg">
<img if.bind="line.type === 'GD'" src="../app/gd.svg">

但这是高维护代码。

另一种可能性是走另一条路。借用建议来放置一个充满imgs的隐藏div,如果这些都是内嵌的,那么可以用绑定来复制图像。

1 个答案:

答案 0 :(得分:4)

使用require.context,您可以告诉webpack捆绑与特定模式匹配的所有文件,然后使用创建的上下文在运行时动态解析其路径。

使用单个上下文和长路径解析所有图像

假设您有一个文件夹src/assets/images,其中包含所有图片。其中一个图像名为image-1.jpg。你可以像这样创建一个文件src/images.js

const imageContext = require.context(
  ".",
  true,
  /^\.\/.*\.(jpe?g|png|gif)$/i
);
export { imageContext };

此上下文将(递归地)包含src下的所有图像。然后在例如app.js中导入并使用它来解析图像:

import { imageContext } from "./images";

export class App {
    constructor() {
        this.img = imageContext("./assets/images/image-1.jpg"); 

        // resolved: '/src/assets/images/image-1.f1224ebcc42b44226aa414bce80fd715.jpg'
    }
}

<img src.bind="img">

解析特定文件夹中的图像,短路径

注意:传递给上下文以解析图像的路径必须相对于您声明它时传递给上下文的路径。所以如果你有src/assets/images.js这样的话:

const imageContext = require.context(
  "./images",
  true,
  /^\.\/.*\.(jpe?g|png|gif)$/i
);
export { imageContext };

然后在src/app.js中你会这样做:

import { imageContext } from "./images";

export class App {
    constructor() {
        this.img = imageContext("./image-1.jpg"); 

        // resolved: '/src/assets/images/image-1.f1224ebcc42b44226aa414bce80fd715.jpg'
    }
}

加载具有特定模式的所有图像

如果要为要一起显示的每组图像创建一个上下文,则会更容易:

的src /页/专辑/ album.js:

const ctx = require.context(
  "../../assets/images",
  true,
  /^\.\/.*some-special-pattern.*\.(jpe?g|png|gif)$/i
);

export class Album {
    constructor() {
        this.images = ctx.keys().forEach(imageContext);
    }
}

<img repeat.for="img of images" src.bind="img">

让Aurelia做一些神奇的

创建一个ValueConverter,例如:

的src /资源/转换器/图像context.js:

const imageContext = require.context(
  "../../",
  true,
  /^\.\/.*\.(jpe?g|png|gif)$/i
);

export class ImageContextValueConverter {
    toView(name) {
        const key = imageContext.keys().find(k => k.includes(name));
        return imageContext(key);
    }
}

的src /资源/ index.js

import { PLATFORM } from "aurelia-pal";

export function configure(config) {
    config.globalResources([
        PLATFORM.moduleName("resources/converters/image-context")
    ]);
}

然后在其他任何地方,例如得到src / assets / images / image-1.jpg:

<img src.bind="'image-1' | imageContext"&GT;

Url-loader问题

当我在我的项目中尝试这样做时,我遇到了url-loader的问题,我无法让它工作。像url-loader这样的感觉被最新的webpack版本打破,因为它也忽略了limit选项。我不得不完全抛弃url-loader来处理图像。如果/当我开始工作时,我会更新我的答案。