11import { encode } from 'blurhash'
2- import { getOptions } from 'loader-utils'
2+ import { getOptions , interpolateName } from 'loader-utils'
3+ import path from 'path'
34import sharp from 'sharp'
45import { loader } from 'webpack'
56
6- const EXPORT_RE = / (?: e x p o r t \s + d e f a u l t | m o d u l e . e x p o r t s \s + = ) (?: \s | $ ) | /
7+ type CreatePath = ( url : string , resourcePath : string , context : string ) => string
78
89type LoaderOptions = {
910 componentX ?: number
1011 componentY ?: number
12+ context ?: string
13+ emitFile ?: boolean
1114 esModule ?: boolean
15+ name ?: string
16+ outputPath ?: string | CreatePath
17+ publicPath ?: string | CreatePath
1218}
1319
14- function loader ( this : loader . LoaderContext , rawContent : Buffer | string ) : void {
20+ function loader ( this : loader . LoaderContext , content : Buffer ) : void {
1521 if ( this . cacheable ) this . cacheable ( )
1622
1723 const callback = this . async ( )
18- const options = getOptions ( this ) as Readonly < LoaderOptions >
19- const esModule =
20- typeof options . esModule !== 'undefined' ? options . esModule : true
24+ const {
25+ context = this . rootContext ,
26+ emitFile = true ,
27+ esModule = true ,
28+ name = '[contenthash].[ext]' ,
29+ ...options
30+ } = getOptions ( this ) as Readonly < LoaderOptions >
2131
22- const content = Buffer . isBuffer ( rawContent )
23- ? rawContent . toString ( 'utf8' )
24- : rawContent
32+ const url = interpolateName ( this , name , {
33+ context,
34+ content
35+ } )
36+
37+ let outputPath : string
38+
39+ if ( typeof options . outputPath !== 'undefined' ) {
40+ if ( typeof options . outputPath === 'function' ) {
41+ outputPath = options . outputPath ( url , this . resourcePath , context )
42+ } else {
43+ outputPath = path . posix . join ( options . outputPath , url )
44+ }
45+ } else {
46+ outputPath = url
47+ }
48+
49+ let publicPath : string
50+
51+ if ( typeof options . publicPath !== 'undefined' ) {
52+ if ( typeof options . publicPath === 'function' ) {
53+ publicPath = options . publicPath ( url , this . resourcePath , context )
54+ } else {
55+ const basePath = options . publicPath . endsWith ( '/' )
56+ ? options . publicPath
57+ : `${ options . publicPath } /`
58+
59+ publicPath = basePath + url
60+ }
61+
62+ publicPath = JSON . stringify ( publicPath )
63+ } else {
64+ publicPath = `__webpack_public_path__ + ${ JSON . stringify ( outputPath ) } `
65+ }
66+
67+ if ( emitFile ) {
68+ this . emitFile ( outputPath , content , null )
69+ }
2570
2671 sharp ( this . resourcePath )
2772 . raw ( )
@@ -39,13 +84,9 @@ function loader(this: loader.LoaderContext, rawContent: Buffer | string): void {
3984 options . componentY || 3
4085 )
4186
42- let result = ''
43-
44- if ( EXPORT_RE . test ( content ) ) {
45- result += `${ content } \n\n`
46- }
47-
48- result += `${
87+ const result = `${
88+ esModule ? 'export default' : 'module.exports ='
89+ } ${ publicPath } \n${
4990 esModule ? 'export const ' : 'exports.'
5091 } blurhash = ${ JSON . stringify ( blurhash ) } \n`
5192
0 commit comments