├── app
├── fonts
│ └── .gitkeep
├── styles
│ └── popup.scss
├── images
│ ├── icon-128.png
│ ├── icon-16.png
│ ├── icon-19.png
│ └── icon-38.png
├── scripts
│ ├── popup.js
│ └── background.js
├── pages
│ └── popup.html
├── component
│ ├── hello.vue
│ └── app.vue
├── _locales
│ └── en
│ │ └── messages.json
└── manifest.json
├── .gitattributes
├── .babelrc
├── tasks
├── default.js
├── clean.js
├── vue.js
├── build.js
├── pages.js
├── locales.js
├── fonts.js
├── images.js
├── manifest.js
├── pack.js
├── lib
│ ├── args.js
│ └── applyBrowserPrefixesFor.js
├── version.js
├── chromereload.js
├── styles.js
└── scripts.js
├── .gitignore
├── promo
├── Screenshot_640x400.png
├── Screenshot_1280x800.png
├── Promo-Image-Large_920x680.png
├── Promo-Image-Small_440x280.png
├── Chrome-Webstore-Icon_128x128.png
└── Promo-Image-Marquee_1400x560.png
├── gulpfile.babel.js
├── .eslintrc
├── .editorconfig
├── LICENSE
├── package.json
└── README.md
/app/fonts/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
2 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"]
3 | }
4 |
--------------------------------------------------------------------------------
/app/styles/popup.scss:
--------------------------------------------------------------------------------
1 | @import "../../node_modules/bulma/bulma.sass";
2 |
--------------------------------------------------------------------------------
/tasks/default.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 |
3 | gulp.task('default', ['build']);
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .DS_Store
3 |
4 | node_modules
5 | npm-debug.log
6 |
7 | dist/
8 | packages/
9 |
--------------------------------------------------------------------------------
/app/images/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/app/images/icon-128.png
--------------------------------------------------------------------------------
/app/images/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/app/images/icon-16.png
--------------------------------------------------------------------------------
/app/images/icon-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/app/images/icon-19.png
--------------------------------------------------------------------------------
/app/images/icon-38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/app/images/icon-38.png
--------------------------------------------------------------------------------
/promo/Screenshot_640x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Screenshot_640x400.png
--------------------------------------------------------------------------------
/promo/Screenshot_1280x800.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Screenshot_1280x800.png
--------------------------------------------------------------------------------
/promo/Promo-Image-Large_920x680.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Promo-Image-Large_920x680.png
--------------------------------------------------------------------------------
/promo/Promo-Image-Small_440x280.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Promo-Image-Small_440x280.png
--------------------------------------------------------------------------------
/promo/Chrome-Webstore-Icon_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Chrome-Webstore-Icon_128x128.png
--------------------------------------------------------------------------------
/promo/Promo-Image-Marquee_1400x560.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/beupgo/vue-chrome-extension-example/HEAD/promo/Promo-Image-Marquee_1400x560.png
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | import requireDir from 'require-dir';
2 |
3 | // Check out the tasks directory
4 | // if you want to modify tasks!
5 | requireDir('./tasks');
6 |
--------------------------------------------------------------------------------
/tasks/clean.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import del from 'del';
3 | import args from './lib/args';
4 |
5 | gulp.task('clean', () => {
6 | return del(`dist/${args.vendor}/**/*`);
7 | });
8 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true
4 | },
5 | "globals": {
6 | "chrome": true,
7 | "crypto": true
8 | },
9 | "parser": "babel-eslint",
10 | "rules": {
11 | "strict": 0
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/scripts/popup.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue';
2 | import App from '../component/app.vue';
3 |
4 | var app=new Vue({
5 | el:'#app',
6 | data:{
7 | name:'vue-chrome-extension'
8 | },
9 | render: h =>h(App)
10 | })
11 |
--------------------------------------------------------------------------------
/tasks/vue.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import vueify from 'gulp-vueify';
3 |
4 |
5 | gulp.task('vue', function () {
6 | return gulp.src('app/component/**/*.vue')
7 | .pipe(vueify())
8 | .pipe(gulp.dest('app/component/'));
9 | });
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/app/scripts/background.js:
--------------------------------------------------------------------------------
1 | // Enable chromereload by uncommenting this line:
2 | // import 'chromereload/devonly';
3 |
4 | chrome.runtime.onInstalled.addListener(function (details) {
5 | console.log('previousVersion', details.previousVersion);
6 | });
7 |
8 | chrome.browserAction.setBadgeText({text: ''});
9 |
--------------------------------------------------------------------------------
/tasks/build.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpSequence from 'gulp-sequence';
3 |
4 | gulp.task('build', gulpSequence(
5 | 'clean', [
6 | 'manifest',
7 | 'scripts',
8 | 'styles',
9 | 'pages',
10 | 'locales',
11 | 'images',
12 | 'fonts',
13 | 'chromereload'
14 | ]
15 | ));
16 |
--------------------------------------------------------------------------------
/app/pages/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Popup
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/tasks/pages.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import livereload from 'gulp-livereload';
4 | import args from './lib/args';
5 |
6 | gulp.task('pages', () => {
7 | return gulp.src('app/pages/**/*.html')
8 | .pipe(gulp.dest(`dist/${args.vendor}/pages`))
9 | .pipe(gulpif(args.watch, livereload()));
10 | });
11 |
--------------------------------------------------------------------------------
/tasks/locales.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import livereload from 'gulp-livereload';
4 | import args from './lib/args';
5 |
6 | gulp.task('locales', () => {
7 | return gulp.src('app/_locales/**/*.json')
8 | .pipe(gulp.dest(`dist/${args.vendor}/_locales`))
9 | .pipe(gulpif(args.watch, livereload()));
10 | });
11 |
--------------------------------------------------------------------------------
/tasks/fonts.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import livereload from 'gulp-livereload';
4 | import args from './lib/args';
5 |
6 | gulp.task('fonts', () => {
7 | return gulp.src('app/fonts/**/*.{woff,woff2,ttf,eot,svg}')
8 | .pipe(gulp.dest(`dist/${args.vendor}/fonts`))
9 | .pipe(gulpif(args.watch, livereload()));
10 | });
11 |
--------------------------------------------------------------------------------
/app/component/hello.vue:
--------------------------------------------------------------------------------
1 |
2 | {{title}}
3 |
4 |
5 |
14 |
15 |
22 |
--------------------------------------------------------------------------------
/tasks/images.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import imagemin from 'gulp-imagemin';
4 | import livereload from 'gulp-livereload';
5 | import args from './lib/args';
6 |
7 | gulp.task('images', () => {
8 | return gulp.src('app/images/**/*')
9 | .pipe(gulpif(args.production, imagemin()))
10 | .pipe(gulp.dest(`dist/${args.vendor}/images`))
11 | .pipe(gulpif(args.watch, livereload()));
12 | });
13 |
--------------------------------------------------------------------------------
/app/_locales/en/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": {
3 | "message": "vue chrome extension example",
4 | "description": "The name of the application"
5 | },
6 | "appShortName": {
7 | "message": "vue_chrome_extension",
8 | "description": "The short_name (maximum of 12 characters recommended) is a short version of the app's name."
9 | },
10 | "appDescription": {
11 | "message": "n",
12 | "description": "The description of the application"
13 | },
14 | "browserActionTitle": {
15 | "message": "vue chrome extension example",
16 | "description": "The title of the browser action button"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/tasks/manifest.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import livereload from 'gulp-livereload';
4 | import jsonTransform from 'gulp-json-transform';
5 | import plumber from 'gulp-plumber';
6 | import applyBrowserPrefixesFor from './lib/applyBrowserPrefixesFor';
7 | import args from './lib/args';
8 |
9 | gulp.task('manifest', () => {
10 | return gulp.src('app/manifest.json')
11 | .pipe(plumber())
12 | .pipe(
13 | jsonTransform(
14 | applyBrowserPrefixesFor(args.vendor)
15 | , 2 /* whitespace */
16 | )
17 | )
18 | .pipe(gulp.dest(`dist/${args.vendor}`))
19 | .pipe(gulpif(args.watch, livereload()));
20 | });
21 |
--------------------------------------------------------------------------------
/tasks/pack.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import { colors, log } from 'gulp-util';
3 | import zip from 'gulp-zip';
4 | import packageDetails from '../package.json';
5 | import args from './lib/args';
6 |
7 | function getPackFileType(){
8 | switch(args.vendor){
9 | case 'firefox':
10 | return '.xpi';
11 | default:
12 | return '.zip';
13 | }
14 | }
15 |
16 | gulp.task('pack', () => {
17 | let name = packageDetails.name;
18 | let version = packageDetails.version;
19 | let filetype = getPackFileType();
20 | let filename = `${name}-${version}-${args.vendor}${filetype}`;
21 | return gulp.src(`dist/${args.vendor}/**/*`)
22 | .pipe(zip(filename))
23 | .pipe(gulp.dest('./packages'))
24 | .on('end', () => {
25 | let distStyled = colors.magenta(`dist/${args.vendor}`);
26 | let filenameStyled = colors.magenta(`./packages/${filename}`);
27 | log(`Packed ${distStyled} to ${filenameStyled}`);
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tasks/lib/args.js:
--------------------------------------------------------------------------------
1 | import yargs from 'yargs';
2 |
3 | const args = yargs
4 |
5 | .option('production', {
6 | boolean: true,
7 | default: false,
8 | describe: 'Minify all scripts and assets'
9 | })
10 |
11 | .option('watch', {
12 | boolean: true,
13 | default: false,
14 | describe: 'Watch all files and start a livereload server'
15 | })
16 |
17 | .option('verbose', {
18 | boolean: true,
19 | default: false,
20 | describe: 'Log additional data'
21 | })
22 |
23 | .option('vendor', {
24 | string: true,
25 | default: 'chrome',
26 | describe: 'Compile the extension for different vendors',
27 | choices: ['chrome', 'firefox', 'opera']
28 | })
29 |
30 | .option('sourcemaps', {
31 | describe: 'Force the creation of sourcemaps'
32 | })
33 |
34 | .argv
35 |
36 | // Use production flag for sourcemaps
37 | // as a fallback
38 | if(typeof args.sourcemaps === 'undefined'){
39 | args.sourcemaps = !args.production;
40 | }
41 |
42 | export default args;
43 |
44 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 快乐动起来
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "__MSG_appName__",
3 | "short_name": "__MSG_appShortName__",
4 | "description": "__MSG_appDescription__",
5 | "version": "0.0.0",
6 | "manifest_version": 2,
7 | "default_locale": "en",
8 | "icons": {
9 | "16": "images/icon-16.png",
10 | "128": "images/icon-128.png"
11 | },
12 | "background": {
13 | "scripts": [
14 | "scripts/background.js"
15 | ]
16 | },
17 | "browser_action": {
18 | "default_icon": {
19 | "19": "images/icon-19.png",
20 | "38": "images/icon-38.png"
21 | },
22 | "default_title": "__MSG_browserActionTitle__",
23 | "default_popup": "pages/popup.html"
24 | },
25 | "permissions": [
26 | "bookmarks",
27 | "clipboardRead",
28 | "clipboardWrite",
29 | "commands",
30 | "contentSettings",
31 | "contextMenus",
32 | "cookies",
33 | "debugger",
34 | "declarativeContent",
35 | "history",
36 | "management",
37 | "notifications",
38 | "pageCapture",
39 | "proxy",
40 | "tabCapture",
41 | "tabs",
42 | "topSites",
43 | "webNavigation",
44 | "webRequest",
45 | "webRequestBlocking",
46 | ""
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/app/component/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | This username is available
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
42 |
43 |
45 |
--------------------------------------------------------------------------------
/tasks/lib/applyBrowserPrefixesFor.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Converts and removes keys with a
3 | * browser prefix to the key without prefix
4 | *
5 | * Example:
6 | *
7 | * __chrome__keyName
8 | * __firefox__keyName
9 | * __opera__keyName
10 | *
11 | * to `keyName`.
12 | * This way we can write one manifest thats valid
13 | * for all browsers
14 | *
15 | * @param {Object} manifest
16 | * @return {Object}
17 | */
18 | export default function applyBrowserPrefixesFor(_vendor){
19 | vendor = _vendor;
20 | return iterator;
21 | };
22 |
23 |
24 | /**
25 | * Vendor key
26 | * @type {String}
27 | */
28 | var vendor = '';
29 |
30 |
31 | /**
32 | * Recursive iterator over all object keys
33 | * @param {Object} obj Object to iterate over
34 | * @return {Object} Processed object
35 | */
36 | function iterator(obj){
37 | Object.keys(obj).forEach((key)=>{
38 | let match = key.match(/^__(chrome|firefox|opera)__(.*)/);
39 | if(match){
40 |
41 | // Swap key with non prefixed name
42 | if(match[1] === vendor){
43 | obj[match[2]] = obj[key];
44 | }
45 |
46 | // Remove the prefixed key
47 | // so it won't cause warings
48 | delete obj[key];
49 | }
50 | else { // no match? try deeper
51 | // Recurse over object's inner keys
52 | if (typeof(obj[key]) === "object") iterator(obj[key]);
53 | }
54 |
55 | });
56 | return obj;
57 | }
58 |
--------------------------------------------------------------------------------
/tasks/version.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bumping version number and tagging the repository with it.
3 | * Please read http://semver.org/
4 | *
5 | * You can use the commands
6 | *
7 | * gulp patch # makes v0.1.0 → v0.1.1
8 | * gulp feature # makes v0.1.1 → v0.2.0
9 | * gulp release # makes v0.2.1 → v1.0.0
10 | *
11 | * To bump the version numbers accordingly after you did a patch,
12 | * introduced a feature or made a backwards-incompatible release.
13 | */
14 |
15 | import gulp from 'gulp';
16 | import git from 'gulp-git';
17 | import bump from 'gulp-bump';
18 | import filter from 'gulp-filter';
19 | import tagVersion from 'gulp-tag-version';
20 |
21 | function inc(importance) {
22 | // get all the files to bump version in
23 | return gulp.src([
24 | 'package.json',
25 | 'app/manifest.json'
26 | ], {
27 | base: "./"
28 | })
29 | // bump the version number in those files
30 | .pipe(bump({
31 | type: importance
32 | }))
33 | // save it back to filesystem
34 | .pipe(gulp.dest('./'))
35 | // commit the changed version number
36 | .pipe(git.commit('bump package version'))
37 | // read only one file to get the version number
38 | .pipe(filter('package.json'))
39 | // **tag it in the repository**
40 | .pipe(tagVersion());
41 | }
42 |
43 | gulp.task('patch', () => {
44 | return inc('patch');
45 | });
46 |
47 | gulp.task('feature', () => {
48 | return inc('minor');
49 | });
50 |
51 | gulp.task('release', () => {
52 | return inc('major');
53 | });
54 |
--------------------------------------------------------------------------------
/tasks/chromereload.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gutil from 'gulp-util';
3 | import gulpSequence from 'gulp-sequence';
4 | import livereload from 'gulp-livereload';
5 | import args from './lib/args';
6 |
7 | // In order to make chromereload work you'll need to include
8 | // the following line in your `scipts/background.js` file.
9 | //
10 | // import 'chromereload/devonly';
11 | //
12 | // This will reload your extension everytime a file changes.
13 | // If you just want to reload a specific context of your extension
14 | // (e.g. `pages/options.html`) include the script in that context
15 | // (e.g. `scripts/options.js`).
16 | //
17 | // Please note that you'll have to restart the gulp task if you
18 | // create new file. We'll fix that when gulp 4 comes out.
19 |
20 | gulp.task('chromereload', (cb) => {
21 |
22 | // This task runs only if the
23 | // watch argument is present!
24 | if (!args.watch) return cb();
25 |
26 | // Start livereload server
27 | livereload.listen({
28 | reloadPage: 'Extension',
29 | quiet: !args.verbose
30 | });
31 |
32 | gutil.log('Starting', gutil.colors.cyan('\'livereload-server\''));
33 |
34 | // The watching for javascript files is done by webpack
35 | // Check out ./tasks/scripts.js for further info.
36 | gulp.watch('app/manifest.json', ['manifest']);
37 | gulp.watch('app/component/**/*.vue',['pages','scripts']);
38 | gulp.watch('app/styles/**/*.css', ['styles:css']);
39 | gulp.watch('app/styles/**/*.less', ['styles:less']);
40 | gulp.watch('app/styles/**/*.scss', ['styles:sass']);
41 | gulp.watch('app/pages/**/*.html', ['pages']);
42 | gulp.watch('app/_locales/**/*', ['locales']);
43 | gulp.watch('app/images/**/*', ['images']);
44 | gulp.watch('app/fonts/**/*.{woff,ttf,eot,svg}', ['fonts']);
45 |
46 | });
47 |
--------------------------------------------------------------------------------
/tasks/styles.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import gutil from 'gulp-util';
4 | import sourcemaps from 'gulp-sourcemaps';
5 | import less from 'gulp-less';
6 | import sass from 'gulp-sass';
7 | import cleanCSS from 'gulp-clean-css';
8 | import livereload from 'gulp-livereload';
9 | import args from './lib/args';
10 |
11 | gulp.task('styles:css', function() {
12 | return gulp.src('app/styles/*.css')
13 | .pipe(gulpif(args.sourcemaps, sourcemaps.init()))
14 | .pipe(gulpif(args.production, cleanCSS()))
15 | .pipe(gulpif(args.sourcemaps, sourcemaps.write()))
16 | .pipe(gulp.dest(`dist/${args.vendor}/styles`))
17 | .pipe(gulpif(args.watch, livereload()));
18 | });
19 |
20 | gulp.task('styles:less', function() {
21 | return gulp.src('app/styles/*.less')
22 | .pipe(gulpif(args.sourcemaps, sourcemaps.init()))
23 | .pipe(less({ paths: ['./app']}).on('error', function(error) {
24 | gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.message));
25 | this.emit('end');
26 | }))
27 | .pipe(gulpif(args.production, cleanCSS()))
28 | .pipe(gulpif(args.sourcemaps, sourcemaps.write()))
29 | .pipe(gulp.dest(`dist/${args.vendor}/styles`))
30 | .pipe(gulpif(args.watch, livereload()));
31 | });
32 |
33 | gulp.task('styles:sass', function() {
34 | return gulp.src('app/styles/*.scss')
35 | .pipe(gulpif(args.sourcemaps, sourcemaps.init()))
36 | .pipe(sass({ includePaths: ['./app']}).on('error', function(error) {
37 | gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.message));
38 | this.emit('end');
39 | }))
40 | .pipe(gulpif(args.production, cleanCSS()))
41 | .pipe(gulpif(args.sourcemaps, sourcemaps.write()))
42 | .pipe(gulp.dest(`dist/${args.vendor}/styles`))
43 | .pipe(gulpif(args.watch, livereload()));
44 | });
45 |
46 | gulp.task('styles', [
47 | 'styles:css',
48 | 'styles:less',
49 | 'styles:sass'
50 | ]);
51 |
52 |
--------------------------------------------------------------------------------
/tasks/scripts.js:
--------------------------------------------------------------------------------
1 | import gulp from 'gulp';
2 | import gulpif from 'gulp-if';
3 | import { log, colors} from 'gulp-util';
4 | import named from 'vinyl-named';
5 | import webpack from 'webpack';
6 | import gulpWebpack from 'webpack-stream';
7 | import plumber from 'gulp-plumber';
8 | import livereload from 'gulp-livereload';
9 | import args from './lib/args';
10 |
11 | const ENV = args.production ? 'production' : 'development';
12 |
13 | gulp.task('scripts', (cb) => {
14 | return gulp.src(['app/scripts/*.js'])
15 | .pipe(plumber({
16 | errorHandler: function() {
17 | // Webpack will log the errors
18 | }
19 | }))
20 | .pipe(named())
21 | .pipe(gulpWebpack({
22 | devtool: args.sourcemaps ? 'inline-source-map': null,
23 | watch: args.watch,
24 | plugins: [
25 | new webpack.DefinePlugin({
26 | 'process.env': {
27 | 'NODE_ENV': JSON.stringify(ENV)
28 | },
29 | '__ENV__': JSON.stringify(ENV),
30 | '__VENDOR__': JSON.stringify(args.vendor)
31 | }),
32 | ].concat(args.production ? [
33 | new webpack.optimize.UglifyJsPlugin()
34 | ] : []),
35 | module: {
36 | preLoaders: [{
37 | test: /\.js$/,
38 | loader: 'eslint-loader',
39 | exclude: /node_modules/
40 | }],
41 | loaders: [{
42 | test: /\.js$/,
43 | loader: 'babel'
44 | },{
45 | test: /\.vue$/,
46 | loader: 'vue-loader'
47 | }]
48 | },
49 | resolve: {
50 | alias: {
51 | 'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
52 | }
53 | },
54 | eslint: {
55 | configFile: '.eslintrc'
56 | }
57 | }, null, (err, stats) => {
58 | log(`Finished '${colors.cyan('scripts')}'`, stats.toString({
59 | chunks: false,
60 | colors: true,
61 | cached: false,
62 | children: false
63 | }));
64 | }))
65 | .pipe(gulp.dest(`dist/${args.vendor}/scripts`))
66 | .pipe(gulpif(args.watch, livereload()));
67 | });
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-chrome-extension-example",
3 | "private": true,
4 | "version": "0.0.0",
5 | "description": "chrome extesion with vue",
6 | "scripts": {
7 | "start": "npm run dev:chrome",
8 | "build": "npm run build:chrome",
9 | "build:chrome": "gulp --production --vendor=chrome && gulp pack --vendor=chrome",
10 | "build:firefox": "gulp --production --vendor=firefox && gulp pack --vendor=firefox",
11 | "build:opera": "gulp --production --vendor=opera && gulp pack --vendor=opera",
12 | "dev": "npm run dev:chrome",
13 | "dev:chrome": "gulp --watch --vendor=chrome",
14 | "dev:firefox": "gulp --watch --vendor=firefox",
15 | "dev:opera": "gulp --watch --vendor=opera"
16 | },
17 | "devDependencies": {
18 | "babel-cli": "6.x.x",
19 | "babel-core": "^6.22.1",
20 | "babel-eslint": "6.x.x",
21 | "babel-loader": "6.x.x",
22 | "babel-plugin-transform-runtime": "^6.22.0",
23 | "babel-preset-es2015": "^6.22.0",
24 | "babel-preset-stage-0": "6.x.x",
25 | "bulma": "^0.3.1",
26 | "chai": "3.x.x",
27 | "chromereload": "0.x.x",
28 | "css-loader": "^0.26.2",
29 | "debounce": "1.x.x",
30 | "del": "2.x.x",
31 | "eslint": "3.x.x",
32 | "eslint-loader": "1.x.x",
33 | "gulp": "3.x.x",
34 | "gulp-bump": "2.x.x",
35 | "gulp-cache": "0.x.x",
36 | "gulp-clean-css": "2.x.x",
37 | "gulp-filter": "4.x.x",
38 | "gulp-git": "1.x.x",
39 | "gulp-if": "2.x.x",
40 | "gulp-imagemin": "3.x.x",
41 | "gulp-json-transform": "0.x.x",
42 | "gulp-less": "3.x.x",
43 | "gulp-livereload": "3.x.x",
44 | "gulp-plumber": "1.x.x",
45 | "gulp-sass": "2.x.x",
46 | "gulp-sequence": "0.x.x",
47 | "gulp-sourcemaps": "1.x.x",
48 | "gulp-tag-version": "1.x.x",
49 | "gulp-util": "3.x.x",
50 | "gulp-vueify": "0.0.3",
51 | "gulp-zip": "3.x.x",
52 | "require-dir": "0.x.x",
53 | "vinyl-named": "1.x.x",
54 | "vue": "^2.2.1",
55 | "vue-loader": "^11.1.4",
56 | "vue-template-compiler": "^2.2.1",
57 | "vueify-insert-css": "^1.0.0",
58 | "webpack": "^2.2.1",
59 | "webpack-stream": "3.x.x",
60 | "yargs": "5.x.x"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue chrome extension example
2 |
3 | develop chrome extension with vue
4 |
5 | ## Installation
6 |
7 | $ npm install
8 |
9 | ## Usage
10 |
11 | Run `$ gulp --watch` and load the `dist`-directory into chrome.
12 |
13 | ## Entryfiles (bundles)
14 |
15 | There are two kinds of entryfiles that create bundles.
16 |
17 | 1. All js-files in the root of the `./app/scripts` directory
18 | 2. All css-,scss- and less-files in the root of the `./app/styles` directory
19 |
20 | ## Tasks
21 |
22 | ### Build
23 |
24 | $ gulp
25 |
26 |
27 | | Option | Description |
28 | |----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|
29 | | `--watch` | Starts a livereload server and watches all assets.
To reload the extension on change include `livereload.js` in your bundle. |
30 | | `--production` | Minifies all assets |
31 | | `--verbose` | Log additional data to the console. |
32 | | `--vendor` | Compile the extension for different vendors (chrome, firefox, opera) Default: chrome |
33 | | `--sourcemaps` | Force the creation of sourcemaps. Default: !production |
34 |
35 |
36 | ### pack
37 |
38 | Zips your `dist` directory and saves it in the `packages` directory.
39 |
40 | $ gulp pack --vendor=firefox
41 |
42 | ### Version
43 |
44 | Increments version number of `manifest.json` and `package.json`,
45 | commits the change to git and adds a git tag.
46 |
47 |
48 | $ gulp patch // => 0.0.X
49 |
50 | or
51 |
52 | $ gulp feature // => 0.X.0
53 |
54 | or
55 |
56 | $ gulp release // => X.0.0
57 |
58 |
59 | ## Globals
60 |
61 | The build tool also defines a variable named `ENV` in your scripts. It will be set to `development` unless you use the `--production` option.
62 |
63 |
64 | **Example:** `./app/background.js`
65 |
66 | if(ENV === 'development'){
67 | console.log('We are in development mode!');
68 | }
69 |
--------------------------------------------------------------------------------