From 71b62f99304880c2a6d822709dcae4d74652b7cb Mon Sep 17 00:00:00 2001 From: Kevin Tjiam Date: Sun, 17 Jun 2018 20:47:24 +0800 Subject: [PATCH] implement WebExtensionPackager --- package.json | 3 +- src/ManifestAsset.js | 2 +- src/WebExtensionPackager.js | 56 +++++++++++++++++++++++++++++++++++++ src/index.js | 1 + test/.gitignore | 1 + test/web-extension.js | 2 +- yarn.lock | 19 ++++++++++++- 7 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 src/WebExtensionPackager.js diff --git a/package.json b/package.json index ff2355c..2c3f56e 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "devDependencies": { "cross-env": "^5.1.6", "mocha": "^5.2.0", - "parcel-bundler": "^1.9.0" + "parcel-bundler": "^1.9.0", + "zip-dir": "^1.0.2" } } diff --git a/src/ManifestAsset.js b/src/ManifestAsset.js index 3db02de..af3d995 100644 --- a/src/ManifestAsset.js +++ b/src/ManifestAsset.js @@ -17,7 +17,7 @@ class ManifestAsset extends Asset { return new JSONAsset(...arguments) } - this.type = basename === 'manifest.json' ? 'json' : 'webmanifest' + this.type = '@@webext' this.isAstDirty = false } diff --git a/src/WebExtensionPackager.js b/src/WebExtensionPackager.js new file mode 100644 index 0000000..44d962b --- /dev/null +++ b/src/WebExtensionPackager.js @@ -0,0 +1,56 @@ +const { promisify } = require('util') +const zipDir = promisify(require('zip-dir')) +const path = require('path') +const fs = require('parcel-bundler/src/utils/fs') +const Packager = require('parcel-bundler/src/packagers/Packager') + +class WebExtensionPackager extends Packager { + async addAsset(asset) { + const artifactsDir = path.resolve( + asset.options.outDir, + '..', + 'artifacts' + ) + await fs.mkdirp(artifactsDir) + + // Write the manifest.json + const bundlePath = path.parse(this.bundle.name) + const contents = await this.resolveAssetContents(asset) + const manifestJsonFilename = path.resolve( + bundlePath.dir, + bundlePath.name + '.json' + ) + await fs.writeFile(manifestJsonFilename, contents, { encoding: 'utf8' }) + + // Package the extension (XPI/CRX) + const zipped = await zipDir(this.options.outDir) + const zippedFilename = path.resolve( + artifactsDir, + bundlePath.name + '.zip' + ) + this.size = zipped.length + await fs.writeFile(zippedFilename, zipped) + } + + async resolveAssetContents(asset) { + let contents = asset.generated[this.bundle.type] + if (!contents || (contents && contents.path)) { + contents = await fs.readFile(contents ? contents.path : asset.name) + } + // Create sub-directories if needed + if (this.bundle.name.includes(path.sep)) { + await fs.mkdirp(path.dirname(this.bundle.name)) + } + return contents + } + + setup() {} + + end() {} + + getSize() { + return this.size || 0 + } +} + +module.exports = WebExtensionPackager diff --git a/src/index.js b/src/index.js index 4f3d33f..31962da 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ function WebExtensionPlugin(bundler) { bundler.addAssetType('json', require.resolve('./ManifestAsset')) + bundler.addPackager('@@webext', require.resolve('./WebExtensionPackager')) } module.exports = WebExtensionPlugin diff --git a/test/.gitignore b/test/.gitignore index 849ddff..2f55563 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1 +1,2 @@ dist/ +artifacts/ diff --git a/test/web-extension.js b/test/web-extension.js index 72db74e..97fa665 100644 --- a/test/web-extension.js +++ b/test/web-extension.js @@ -8,7 +8,7 @@ describe('WebExtension', () => { const bundle = await bundler.bundle() await assertBundleTree(bundle, { - type: 'json', + type: '@@webext', assets: ['manifest.json'], childBundles: [ { name: 'background_script.js' }, diff --git a/yarn.lock b/yarn.lock index 112fce0..61d1e1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -104,6 +104,10 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + atob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" @@ -2033,6 +2037,12 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jszip@^2.4.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-2.6.1.tgz#b88f3a7b2e67a2a048152982c7a3756d9c4828f0" + dependencies: + pako "~1.0.2" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -2475,7 +2485,7 @@ pako@^0.2.5: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" -pako@~1.0.5: +pako@~1.0.2, pako@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" @@ -3643,3 +3653,10 @@ yallist@^2.1.2: yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +zip-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/zip-dir/-/zip-dir-1.0.2.tgz#253f907aead62a21acd8721d8b88032b2411c051" + dependencies: + async "^1.5.2" + jszip "^2.4.0"