diff --git a/package.json b/package.json index 18f1af0..6915b25 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@types/firefox-webext-browser": "^82.0.0", "@types/fs-extra": "^9.0.11", "@types/jest": "^26.0.23", + "@types/klaw": "^3.0.2", "@types/node": "^16.0.0", "@types/webpack": "4", "@types/ws": "^7.4.6", @@ -38,6 +39,7 @@ }, "dependencies": { "fs-extra": "^10.0.0", + "klaw": "^3.0.0", "webpack-inject-plugin": "^1.5.5", "ws": "^7.5.2" } diff --git a/src/BrowserExtensionPlugin.ts b/src/BrowserExtensionPlugin.ts index 15f57d5..f91c3ad 100644 --- a/src/BrowserExtensionPlugin.ts +++ b/src/BrowserExtensionPlugin.ts @@ -1,11 +1,11 @@ import path from 'path' import https from 'https' import fs from 'fs-extra' +import walk from 'klaw' import InjectPlugin, { ENTRY_ORDER } from 'webpack-inject-plugin' import WebSocket from 'ws' import { compileTemplate } from './compileTemplate' import type webpack from 'webpack' - export class BrowserExtensionPlugin { port: number host: string @@ -98,11 +98,24 @@ export class BrowserExtensionPlugin { compiler.hooks.done.tap(name, this.done.bind(this)) this.addClient(compiler) } - if (this.manifestFilePath) { - await this.compileManifest(compiler) + compiler.hooks.emit.tapPromise(name, this.emit.bind(this)) + } + + /** + * emit add file to the emit that is happening to make sure the files are emitted at the correct hook + */ + async emit(compilation: webpack.compilation.Compilation) { + const manifest = await this.compileManifest(compilation.compiler) + const locales = await this.getLocales(compilation.compiler) + + if (manifest) { + compilation.assets['manifest.json'] = manifest } - if (this.localeDirectory) { - await this.syncLocales(compiler) + + if (locales) { + locales.forEach(locale => { + compilation.assets[locale.file] = locale.asset + }) } } @@ -120,7 +133,7 @@ export class BrowserExtensionPlugin { } if (changedFiles.some(file => file.includes('_locales'))) { - await this.syncLocales(compiler) + await this.getLocales(compiler) } return this.startServer() @@ -145,12 +158,6 @@ export class BrowserExtensionPlugin { */ afterCompile(compilation: webpack.compilation.Compilation) { this.notifyExtension({ action: 'afterCompile' }) - if (this.manifestFilePath) { - compilation.fileDependencies.add(path.resolve(this.manifestFilePath)) - } - if (this.localeDirectory) { - compilation.contextDependencies.add(path.resolve(this.localeDirectory)) - } } notifyExtension(data: { [key: string]: any }) { @@ -211,26 +218,60 @@ export class BrowserExtensionPlugin { manifest = await this.onCompileManifest(manifest) } - await fs.writeFile( - path.resolve(compiler.outputPath, 'manifest.json'), - JSON.stringify(manifest, null, 2), - ) + const source = JSON.stringify(manifest, null, 2) + + return { + source: () => source, + size: () => source.length, + } } catch (err) { this.log(`failed to compile manifest: ${err.message}`) } } + return null } /** * Sync locales with webpack */ - async syncLocales(compiler: webpack.Compiler) { - if (this.localeDirectory) { - await fs.copySync( - this.localeDirectory, - path.resolve(compiler.outputPath, './_locales'), - ) + async getLocales(compiler: webpack.Compiler) { + const { localeDirectory } = this + if (localeDirectory) { + const files = await this.getFilesInDirectory(localeDirectory) + return files.map(file => ({ + file: `_locales/${path.relative(localeDirectory, file)}`, + asset: { + source: () => fs.readFileSync(file, 'utf8'), + size: () => fs.statSync(file).size, + }, + })) } + return [] + } + + async getFilesInDirectory(directory: string): Promise> { + return new Promise((resolve, reject) => { + const files: Array = [] + walk(directory, { + filter: item => { + const basename = path.basename(item) + return basename === '.' || basename[0] !== '.' + }, + }) + .on('data', file => { + const path = file.path + const isFile = file.stats.isFile() + if (isFile) { + files.push(path) + } + }) + .on('end', () => { + resolve(files) + }) + .on('error', err => { + reject(err) + }) + }) } /** diff --git a/yarn.lock b/yarn.lock index 28f52d6..1220a60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1231,6 +1231,13 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" +"@types/klaw@^3.0.2": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/klaw/-/klaw-3.0.2.tgz#ce9cf2c0566b806d4fe86eb07082b483ad1ee3f6" + integrity sha512-v8smJUQ5SuoCh1EZ5B429DTGFDE0URnC9ix3wJpTB8Ofk7Rgi5Hj/jm9GffavHiXPeYgPRe3ASBfB6LT6ytceg== + dependencies: + "@types/node" "*" + "@types/node@*", "@types/node@^16.0.0": version "16.0.0" resolved "https://registry.npmjs.org/@types/node/-/node-16.0.0.tgz#067a6c49dc7a5c2412a505628e26902ae967bf6f" @@ -1977,7 +1984,7 @@ globals@^11.1.0: resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: +graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== @@ -2664,6 +2671,13 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"