Awesome
ts-transform-asset - Typescript transformer for asset imports
This transformer will simply convert imports or reexports like:
import foo from './images/foo.gif'
import * as bar from '../images/bar.png'
export { default } from './foobar.svg'
export { default as foobar } from './foobar.ico'
to:
const foo = 'assets/foo.gif'
const bar = 'assets/bar.png'
const foobar_svg_1 = 'assets/foobar.svg'
export default foobar_svg_1
export const foobar = 'assets/foobar.ico'
Language/langue
Documents, messages, code (including variable names and comments), are in English.
Anyway, because Slune is French firm, all documents and important messages must also be provided in French. Other translations are welcome.
:fr: Une version française de ce document se trouve ici.
Installation
Installation is done using npm install
command:
$ npm install --save-dev ts-transform-asset
Why would I need that?
You have a project using Webpack
with the file-loader
plugin. When this plugin finds an import foo from "./images/foo.gif"
, it copies foo.gif
to an assets directory and change the usage of foo
using the public path to the file. Great.
Then, you have another project, which contains the web server. This server, which depends on the previous project, will take the bundle and all assets to serve them to the clients. But you also want to do some server side rendering (SSR). And for this, you cannot use the bundle created by Webpack
because it does not have an appropriate entry point for the server (e.g. you need to use a StaticRouter
instead of a BrowserRouter
). Or maybe you prefer using the transpiled javascript
and definition files instead of the minified and untyped bundle.
Unfortunately, this is not working, because your server do not know what to do with your assets files.
Using this transformer to transpile the web pages (not for Webpack
!), you will convert your imports into constants with the URL of where resources should be found, and dependents project will be able to work without any more configuration.
Usage
The transformer accepts the following parameters:
assetsMatch
: a regular expression used to select asset imports, e.g., for all.png
files,assetsMatch = "\\.png$"
. This parameter is mandatory.targetName
: a template similar to Webpack file-loader name used to convert the name of the asset. If you defined apublicPath
in theoutput
parameter ofWebpack
, then you will probably need to specify this path here too. This parameter is optional and defaults to[hash].[ext]
.
There is currently no way of declaring a transformer in the vanilla TypeScript compiler. If you do not want to write your own compiler using the typescript
API, you can use the ttypescript wrapper.
Code
Your TypeScript code should already be well written if you are using Webpack
and the file-loader
. If not, you can follow the instructions below.
Module declaration
Before using them, you need to declare the new module types, for example in an assets.d.ts
file like this:
declare module '*.png' {
const content: string
export default content
}
Older versions of file-loader
(before 5.0.2) where not using a default export. You should then declare module types this way in this case:
declare module '*.png' {
const content: string
export = content
}
Asset import
When the (module) file is to be used:
import image from './image.png'
const url: string = image
It is even possible to re-export the asset file:
export { default as image } from './image.png'
Then, in another file:
import { image } from '../images'
const url: string = image
For older versions of file-loader
(before 5.0.2), only namespace import is possible:
import * as image from './image.png'
const url: string = image
Configuration with ttypescript
For ttypescript
, configure your tsconfig.json
. Example:
{
"compilerOptions": {
"plugins": [
{
"transform": "ts-transform-asset",
"assetsMatch": "\\.png$",
"targetName": "assets/[name]-[hash].[ext]"
}
]
}
}
Notices
- The transformer will not detect nor modify any
require
statement. It is advised to run it in thebefore
phase of the compilation, before the code is converted to an older version ofECMAScript
. - The transformer either modify the code if it conforms to what is expected, or do not touch it at all. There is an exception anyway for the re-export declarations: if the source module matches the given parameters, but the exported property is not
default
, then this export property will be removed.
Migration
Prior to version 3.x.x
Prior to version 3.x.x, there was a configuration entry targetPath
which was the prefix used to add to the target asset name. Everything is now defined in the new targetName
entry. Converting from previous to current configuration is as simple as the below example:
"transform": "ts-transform-asset",
"assetsMatch": "\\.png$",
- "targetPath": "assets"
+ "targetName": "assets/[name].[ext]"
}
]
Prior to version 2.x.x
In addition to the previous modifications, note that prior to version 2.x.x, transformer was of type config
. Since version 2.0.0, transformer is of type program
, which is the default. If you are upgrading from an older version and using ttypescript
, you have to update the plugin
configuration in tsconfig.json
:
{
"transform": "ts-transform-asset",
- "type": "config",
"assetsMatch": "\\.png$",
"targetName": "assets/[name].[ext]"
Contributing
Even though we cannot guarantee a response time, please feel free to file an issue if you have any question or problem using the package.
Pull Requests are welcome. You can, of course, submit corrections or improvements for code, but do not hesitate to also improve documentation, even for small spell or grammar errors.