Skip to content

Commit

Permalink
Merge pull request #5 from adambullmer/prod-build-keys
Browse files Browse the repository at this point in the history
Prod build keys
Fixed #4
  • Loading branch information
adambullmer committed Jul 17, 2018
2 parents e9d0140 + f178c77 commit 691e0d2
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 32 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ This can be added to your vuejs project by one of the following methods:
## Usage
Running the Livereload server.
This will build and write to the local `dist` directory.
This plugin will respect the `outputDir` setting, however it cannot read into passed CLI args, so if you require a custom output dir, be sure to add it in your `vue.config.js` file.
You can then add this as an unpacked plugin to your browser, and will continue to update as you make changes.
**NOTE:** you cannot get HMR support in the popup window, however, closing and reopening will refresh your content.

```sh
yarn ext-serve
yarn serve
yarn build
```


Expand All @@ -62,15 +64,14 @@ yarn test
```

## Roadmap
- Add generators for background.js, popup, vuex, and vue-router stuff. (Make startup a breeze)
- Add some generator options for other pieces of browser extensions. This includes scaffolding the components/dirs, and registering the build options into the build time hooks.
- Dev Tools
- Dedicated extension pages
- Options Pages
- Content scripts
- Add zipping to the bundle for production builds
- More configurability in scaffolding, like Kocal/vue-web-extension does
- A preset
- Key Generation

## Credits
- [https://github.com/Kocal/vue-web-extension](https://github.com/Kocal/vue-web-extension) For inspiration on app and build structure
Expand Down
17 changes: 16 additions & 1 deletion generator/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
const fs = require('fs')
const gitignoreSnippet = `
# Vue Browser Extension Output
*.pem
*.pub
*.zip
/dist-zip
`

module.exports = (api, { config }) => {
const eslintConfig = { env: { webextensions: true } }
const pkg = {
private: true,
scripts: {
'ext-serve': 'vue-cli-service ext-serve --mode development'
'serve': 'vue-cli-service build --mode development --watch'
},
dependencies: {
'vue-router': '^3.0.1',
Expand All @@ -17,4 +27,9 @@ module.exports = (api, { config }) => {

api.extendPackage(pkg)
api.render('./template')

api.onCreateComplete(() => {
const gitignore = fs.readFileSync(api.resolve('./.gitignore'), 'utf8')
fs.writeFileSync(api.resolve('./.gitignore'), gitignore + gitignoreSnippet)
})
}
71 changes: 47 additions & 24 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,70 @@
const path = require('path')
const { log } = require('@vue/cli-shared-utils')
const fs = require('fs')
const { exec } = require('child_process')
const logger = require('@vue/cli-shared-utils')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const ChromeExtensionReloader = require('webpack-chrome-extension-reloader')
const WebpackShellPlugin = require('webpack-shell-plugin-next')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { name, version } = require(path.join(process.cwd(), 'package.json'))

const appRootPath = process.cwd()

module.exports = (api) => {
api.configureWebpack(webpackConfig => {
const { name, version } = require(path.join(appRootPath, 'package.json'))
const isDevelopment = api.service.mode === 'development'
const isProduction = api.service.mode === 'production'
const outputDir = api.resolve(api.service.projectOptions.outputDir || 'dist')
const packageScript = isProduction ? 'build-zip.js' : 'remove-evals.js'

api.configureWebpack((webpackConfig) => {
webpackConfig.output.filename = '[name].js'
webpackConfig.output.chunkFilename = 'js/[id].[name].js?[hash:8]'

delete webpackConfig.entry.app
webpackConfig.entry.background = './src/background.js'
webpackConfig.entry['popup/popup'] = './src/popup/popup.js'

if (isProduction) {
webpackConfig.plugins.push(new CopyWebpackPlugin([{ from: './key.pem', to: 'key.pem' }]))
}

webpackConfig.plugins.push(new CopyWebpackPlugin([
{ from: './src/icons', to: 'icons/[name].[ext]', ignore: ['icon.xcf'] },
{
from: './src/manifest.json',
to: 'manifest.json',
transform: (content) => {
const jsonContent = JSON.parse(content)
jsonContent.version = version
return new Promise((resolve, reject) => {
const jsonContent = JSON.parse(content)
jsonContent.version = version

if (process.env.NODE_ENV === 'development') {
jsonContent['content_security_policy'] = "script-src 'self' 'unsafe-eval'; object-src 'self'"
}
if (isProduction) {
return resolve(JSON.stringify(jsonContent, null, 2))
}

jsonContent.content_security_policy = "script-src 'self' 'unsafe-eval'; object-src 'self'"

return JSON.stringify(jsonContent, null, 2)
try {
const keyfile = path.join(appRootPath, 'key.pem')
fs.statSync(keyfile)

return exec(`openssl rsa -in ${keyfile} -pubout -outform DER | openssl base64 -A`, (error, stdout) => {
if (error) {
// node couldn't execute the command
reject(error)
}

jsonContent.key = stdout
resolve(JSON.stringify(jsonContent, null, 2))
})
} catch (error) {
if (isProduction) {
logger.error('no key.pem file found. You cannot publish to the chrome store without one. If this is your first publish, chrome will make a key for you, and you can ignore this message')
} else {
logger.warn('No key.pem file found. This is fine for dev, however you may have problems publishing without one')
}
}
})
}
}
]))
Expand All @@ -44,16 +80,15 @@ module.exports = (api) => {
chunks: ['popup/popup', 'chunk-vendors']
}))

const scriptPath = path.join(__dirname, 'scripts/remove-evals.js')
webpackConfig.plugins.push(new WebpackShellPlugin({
onBuildExit: {
scripts: [`node ${scriptPath}`],
scripts: [`node ${path.join(__dirname, 'scripts', packageScript)} ${outputDir}`],
blocking: true,
parallel: false
}
}))

if (process.env.NODE_ENV === 'development') {
if (isDevelopment) {
webpackConfig.plugins = (webpackConfig.plugins || []).concat([
new ChromeExtensionReloader({
entries: {
Expand All @@ -63,16 +98,4 @@ module.exports = (api) => {
])
}
})

api.registerCommand('ext-serve', {
description: 'Builds and watches the project, writing the files to the output directory'
}, (...args) => {
log('Starting webpack in watch mode...')

api.configureWebpack((webpackConfig) => {
webpackConfig.watch = true
})

api.service.run('build', ...args)
})
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vue-cli-plugin-browser-extension",
"version": "0.3.3",
"version": "0.4.0",
"description": "Browser extension development plugin for vue-cli 3.0",
"main": "index.js",
"scripts": {
Expand Down Expand Up @@ -29,6 +29,7 @@
"html-webpack-plugin": "^3.2.0",
"webpack": "^4.16.0",
"webpack-chrome-extension-reloader": "^0.8.3",
"webpack-shell-plugin-next": "https://github.com/adambullmer/webpack-shell-plugin-next.git"
"webpack-shell-plugin-next": "https://github.com/adambullmer/webpack-shell-plugin-next.git",
"zip-folder": "^1.0.0"
}
}
42 changes: 42 additions & 0 deletions scripts/build-zip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env node

const fs = require('fs')
const path = require('path')
const zipFolder = require('zip-folder')

const appRootPath = process.cwd()
const DEST_DIR = process.argv[2]
const DEST_ZIP_DIR = path.join(appRootPath, `${DEST_DIR}-zip`)
const { name, version } = require(path.join(appRootPath, 'package.json'))

const makeDestZipDirIfNotExists = () => {
if (!fs.existsSync(DEST_ZIP_DIR)) {
fs.mkdirSync(DEST_ZIP_DIR)
}
}

const buildZip = (src, dist, zipFilename) => {
console.info(`Building ${zipFilename}...`)

return new Promise((resolve, reject) => {
zipFolder(src, path.join(dist, zipFilename), (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}

const main = () => {
const zipFilename = `${name}-v${version}.zip`

makeDestZipDirIfNotExists()

buildZip(DEST_DIR, DEST_ZIP_DIR, zipFilename)
.then(() => console.info('OK'))
.catch(console.err)
}

main()
2 changes: 1 addition & 1 deletion scripts/remove-evals.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const path = require('path')
const fs = require('fs')
const BUNDLE_DIR = 'dist'
const BUNDLE_DIR = process.argv[2]
const bundles = [
'background.js',
'popup/popup.js'
Expand Down
Loading

0 comments on commit 691e0d2

Please sign in to comment.