66import fs from 'fs-extra'
77import path from 'path'
88import { calcDataDigest , getLastLoaderPath } from '../common/utils'
9- import { LOADER_INFO_LIST , LOADER_PATH_UX } from '../common/constant'
9+ import {
10+ LOADER_INFO_LIST ,
11+ LOADER_PATH_UX ,
12+ LOADER_PATH_APP ,
13+ LOADER_PATH_DEVICETYPE
14+ } from '../common/constant'
1015
1116const MANIFEST_PATH = 'manifest.json'
1217
@@ -24,6 +29,10 @@ const EXCLUDE_FILE_EXTS = [
2429 ''
2530] // .gitignore .DS_Store
2631
32+ const EXCLUDE_FILES = [ 'manifest.json' , 'sitemap.json' ]
33+
34+ const APP = 'app'
35+
2736/**
2837 * Generate a fingerprint string for a widget, based on the source code and config of the widget.
2938 * The fingerprint can be used to detect whether any changes on the widget.
@@ -56,67 +65,108 @@ class WidgetFingerprintPlugin {
5665 }
5766 const widgets = options . widgets || { }
5867 const widgetNameKeyMap = { }
59- const widgetEntries = Object . keys ( widgets ) . map ( ( key ) => {
68+ const widgetKeys = Object . keys ( widgets ) || { }
69+ const widgetEntries = widgetKeys . map ( ( key ) => {
6070 const widget = widgets [ key ]
6171 const name = path . join ( key , widget . component )
6272 widgetNameKeyMap [ name ] = key
6373 return name
6474 } )
75+ const allAssetsDigestMap = this . calculateAllAssetsDigest ( pathSrc , pathSrc , { } , widgetKeys )
76+ const appDigestMap = { }
6577 for ( const chunk of compilation . chunks ) {
6678 const chunkName = chunk . name
6779 if ( widgetEntries . indexOf ( chunkName ) >= 0 ) {
6880 // widget chunk
69- const widgetKey = widgetNameKeyMap [ chunkName ]
7081 const widgetDigestMap = { }
71- const arr = [ ]
72- for ( const module of compilation . chunkGraph . getChunkModules ( chunk ) ) {
73- const { _source, rawRequest, request } = module
74- arr . push ( rawRequest )
75- if ( ! request ) {
76- continue
77- }
78- const reqPath = request . replace ( / \\ / g, '/' )
79- const lastLoaderPath = getLastLoaderPath ( reqPath )
80- if ( lastLoaderPath === LOADER_PATH_UX . path ) {
81- // skip ux-loader.js
82- continue
83- }
84- const { absPath } = this . parseABSPath ( reqPath , pathSrc )
85- const { _valueAsString, _valueAsBuffer } = _source || { }
86- const sourceValueStr = _valueAsString || _valueAsBuffer ?. toString ( ) || ''
87- let digestStr = ''
88- if ( sourceValueStr !== '' ) {
89- const digest = calcDataDigest ( Buffer . from ( sourceValueStr , 'utf-8' ) )
90- digestStr = digest . toString ( 'hex' )
91- }
92- // module digest
93- widgetDigestMap [ absPath ] = digestStr
94- }
95- // assets digests
96- const assetsDigestMap = this . calculateAssetsDigest ( path . join ( pathSrc , widgetKey ) , pathSrc )
97- Object . assign ( widgetDigestMap , assetsDigestMap )
98-
99- // widget manifest digest
100- const manifestDigest = this . getManifestDigest ( widgetKey , manifestContent )
101- widgetDigestMap [ MANIFEST_PATH ] = manifestDigest
102-
103- const orderK = Object . keys ( widgetDigestMap ) . sort ( )
104- let contentStr = '' // ordered path & digest string
105- orderK . forEach ( ( filePath ) => {
106- contentStr += `${ filePath } :${ widgetDigestMap [ filePath ] } ;`
107- } )
108- // generate widget digest, save it in compilation
109- const widgetDigest = calcDataDigest ( Buffer . from ( contentStr , 'utf-8' ) ) . toString ( 'hex' )
110- const { _widgetDigestMap = { } } = compilation
111- _widgetDigestMap [ `widget:${ widgetKey } ` ] = widgetDigest
112- if ( ! compilation . _widgetDigestMap ) {
113- compilation . _widgetDigestMap = _widgetDigestMap
114- }
82+ this . getModuleDigestFromChunk ( compilation , chunk , widgetDigestMap , pathSrc )
83+ const widgetKey = widgetNameKeyMap [ chunkName ]
84+ this . updateDigest (
85+ compilation ,
86+ widgetKey ,
87+ widgetDigestMap ,
88+ allAssetsDigestMap ,
89+ manifestContent
90+ )
91+ } else {
92+ // appDigestMap
93+ this . getModuleDigestFromChunk ( compilation , chunk , appDigestMap , pathSrc )
11594 }
11695 }
96+ this . updateDigest ( compilation , APP , appDigestMap , allAssetsDigestMap , manifestContent )
11797 } )
11898 }
11999
100+ /**
101+ * combine assets and manifest digests, save result on compilation
102+ * @param {* } compilation
103+ * @param {* } key app or widgets key
104+ * @param {* } digestMap all digest for app & widgets
105+ * @param {* } allAssetsDigestMap all assets digets
106+ * @param {* } manifestContent manifest conentent
107+ */
108+ updateDigest ( compilation , key , digestMap , allAssetsDigestMap , manifestContent ) {
109+ // assets digest
110+ const assetsDigestMap = allAssetsDigestMap [ key ] || { }
111+ Object . assign ( digestMap , assetsDigestMap )
112+ // manifest digest
113+ digestMap [ MANIFEST_PATH ] = this . getManifestDigest ( key , manifestContent )
114+
115+ const orderK = Object . keys ( digestMap ) . sort ( )
116+ let contentStr = '' // ordered path & digest string
117+ orderK . forEach ( ( filePath ) => {
118+ contentStr += `${ filePath } :${ digestMap [ filePath ] } ;`
119+ } )
120+ // generate widget digest, save it in compilation
121+ const digest = calcDataDigest ( Buffer . from ( contentStr , 'utf-8' ) ) . toString ( 'hex' )
122+
123+ const { _widgetDigestMap = { } } = compilation
124+ if ( key === APP ) {
125+ _widgetDigestMap [ `app:${ key } ` ] = digest
126+ } else {
127+ _widgetDigestMap [ `widget:${ key } ` ] = digest
128+ }
129+ if ( ! compilation . _widgetDigestMap ) {
130+ compilation . _widgetDigestMap = _widgetDigestMap
131+ }
132+ }
133+
134+ /**
135+ * get all module digests in chunk
136+ * @param {* } compilation
137+ * @param {* } chunk
138+ * @param {* } moduleDigestMap
139+ * @param {* } pathSrc
140+ */
141+ getModuleDigestFromChunk ( compilation , chunk , moduleDigestMap , pathSrc ) {
142+ for ( const module of compilation . chunkGraph . getChunkModules ( chunk ) ) {
143+ const { _source, request } = module
144+ if ( ! request ) {
145+ continue
146+ }
147+ const reqPath = request . replace ( / \\ / g, '/' )
148+ const lastLoaderPath = getLastLoaderPath ( reqPath )
149+ if (
150+ lastLoaderPath === LOADER_PATH_UX . path ||
151+ lastLoaderPath === LOADER_PATH_APP . path ||
152+ lastLoaderPath === LOADER_PATH_DEVICETYPE . path
153+ ) {
154+ // skip
155+ continue
156+ }
157+ const { absPath } = this . parseABSPath ( reqPath , pathSrc )
158+ const { _valueAsString, _valueAsBuffer } = _source || { }
159+ const sourceValueStr = _valueAsString || _valueAsBuffer ?. toString ( ) || ''
160+ let digestStr = ''
161+ if ( sourceValueStr !== '' ) {
162+ const digest = calcDataDigest ( Buffer . from ( sourceValueStr , 'utf-8' ) )
163+ digestStr = digest . toString ( 'hex' )
164+ }
165+ // module digest
166+ moduleDigestMap [ absPath ] = digestStr
167+ }
168+ }
169+
120170 /**
121171 * parse absolute path based by project src
122172 * @param {* } reqPath
@@ -147,24 +197,32 @@ class WidgetFingerprintPlugin {
147197 }
148198
149199 /**
150- * 返回与当前卡片相关的 manifest 配置摘要
151- * @param string widgetKey
200+ * 返回与当前app或widget相关的 manifest 配置摘要
201+ * @param string key
152202 * @param string manifestContent
153203 */
154- getManifestDigest ( widgetKey , manifestContent ) {
155- if ( ! widgetKey || ! manifestContent ) {
204+ getManifestDigest ( key , manifestContent ) {
205+ if ( ! key || ! manifestContent ) {
156206 return new Date ( ) . getTime ( )
157207 }
158208 const manifestJsonNew = JSON . parse ( manifestContent )
159209 manifestJsonNew . versionName = ''
160210 manifestJsonNew . versionCode = ''
161- manifestJsonNew . router . entry = ''
162- if ( manifestJsonNew . router . pages ) {
163- manifestJsonNew . router . pages = ''
164- }
165- manifestJsonNew . router . widgets = {
166- [ widgetKey ] : manifestJsonNew . router . widgets [ widgetKey ]
211+ manifestJsonNew [ 'template/official' ] = ''
212+ if ( key === APP ) {
213+ if ( manifestJsonNew . router . widgets ) {
214+ manifestJsonNew . router . widgets = ''
215+ }
216+ } else {
217+ manifestJsonNew . router . entry = ''
218+ if ( manifestJsonNew . router . pages ) {
219+ manifestJsonNew . router . pages = ''
220+ }
221+ manifestJsonNew . router . widgets = {
222+ [ key ] : manifestJsonNew . router . widgets [ key ]
223+ }
167224 }
225+
168226 const manifestJsonNewStr = JSON . stringify ( manifestJsonNew )
169227 const digest = calcDataDigest ( Buffer . from ( manifestJsonNewStr , 'utf-8' ) ) . toString ( 'hex' )
170228 return digest
@@ -176,20 +234,38 @@ class WidgetFingerprintPlugin {
176234 * @param {string[] } allFiles
177235 * @returns {Object } relative file path and its digest
178236 */
179- calculateAssetsDigest ( dir , basePath , assetsDigestMap = { } ) {
237+ calculateAllAssetsDigest ( dir , basePath , assetsDigestMap , widgetKeys ) {
180238 const files = fs . readdirSync ( dir )
181239 for ( let i = 0 ; i < files . length ; i ++ ) {
182- let name = path . join ( dir , files [ i ] )
183- if ( fs . statSync ( name ) . isDirectory ( ) ) {
184- this . calculateAssetsDigest ( name , basePath , assetsDigestMap )
240+ let fileName = path . join ( dir , files [ i ] )
241+ if ( fs . statSync ( fileName ) . isDirectory ( ) ) {
242+ // directory
243+ this . calculateAllAssetsDigest ( fileName , basePath , assetsDigestMap , widgetKeys )
185244 } else {
186- const ext = path . extname ( name )
245+ // file
246+ const ext = path . extname ( fileName )
187247 if ( EXCLUDE_FILE_EXTS . includes ( ext ) ) {
188248 continue
189249 }
190- const digest = calcDataDigest ( fs . readFileSync ( name ) ) . toString ( 'hex' )
191- const relativePath = path . relative ( basePath , name )
192- assetsDigestMap [ relativePath ] = digest
250+ const relativePath = path . relative ( basePath , fileName )
251+ if ( EXCLUDE_FILES . includes ( relativePath ) ) {
252+ continue
253+ }
254+ const digest = calcDataDigest ( fs . readFileSync ( fileName ) ) . toString ( 'hex' )
255+ const widgetKey = widgetKeys . find ( ( item ) => relativePath . startsWith ( item + '/' ) )
256+ if ( widgetKey ) {
257+ // widget
258+ if ( ! assetsDigestMap [ widgetKey ] ) {
259+ assetsDigestMap [ widgetKey ] = { }
260+ }
261+ assetsDigestMap [ widgetKey ] [ relativePath ] = digest
262+ } else {
263+ // app
264+ if ( ! assetsDigestMap [ APP ] ) {
265+ assetsDigestMap [ APP ] = { }
266+ }
267+ assetsDigestMap [ APP ] [ relativePath ] = digest
268+ }
193269 }
194270 }
195271 return assetsDigestMap
0 commit comments