Skip to main content

Images

Images in webpack are treated as a regular files with an exception of optionally being converted to base64 string and HTML inlined. Further optimizations are possible using more specialized loaders (ex. compression). Using more special image transformations depends on a specific application needs and image formats.

Dependencies

npm i file-loader url-loader -D --save-exact
  • url-loader - webpack loader for optional image conversion to base64 URI
  • file-loader - webpack loader for importing files from JavaScript and copying to the output folder

We are using only two loaders to demonstrate a general purpose idea of loading images. Every image has to be imported by the JavaScript code. This step is handled by the file-loader. During compilation, every image discovered could be translated to a base64 string to be embedded within the HTML code. This step is prepared by the url-loader.

Webpack configuration

webpack/parts.ts

Add one more loader to webpack/parts.ts

//...
{
test: /\.(png|jpg|gif|bmp)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '../img/[name].[ext]'
}
}]
}
//...

We are using url-loader to configure image file extensions used by the application. Following options are applied:

  • limit - maximum file size in bytes under which images are converted to base64. When exceeded, file-loader is used as a fallback loader.
  • name - output file name (might include relative file path). [name] - file name placeholder, [ext] - file extension placeholder.

Fallback loader could be specified explicitly as one of the options. In this case, all additional parameters specified under the options section will be passed through.

With this setup, all images are copied to the img folder under the output folder.

TypeScript configuration

Images could be stored in a different places within a source folder. For those situations where images are stored in on folder, it is a good idea to configure an alias to refer to within the TypeScript code.

tsconfig.json

...
"paths": {
"@app": ["./src/app"],
"@app/*": ["./src/app/*"],
"@components/*": ["./src/app/components/*"],
"@utils": ["./src/utils"],
"@img/*": ["./assets/images/"]
}
...

Also, TypeScript is not aware of importing image files using JavaScript module import syntax.

src/global.d.ts

Create src/global.d.ts file

declare module "*.png" {
const value: string
export default value
}

declare module "*.jpg" {
const value: string
export default value
}

We declared two modules with corresponding extensions to make sure no compilation errors when importing image files with corresponding extensions.

Babel configuration

Just to match TypeScript configuration, we need to alter babel config as well.

babel.config.js

//...
alias: {
"@app": "./src/app",
"@components": "./src/app/components",
"@utils": "./src/utils",
"@img": "./assets/images"
}
//...

Sources

src/app/index.ts

//...
import largeLogo from '@img/logo1.png'
import smallLogo from '@img/logo2.jpg'

//...

const largeImage = createImage(largeLogo, 'large')
largeImage.render()

const smallImage = createImage(smallLogo, 'small')
smallImage.render()
//...

Final version

Reference implementation