├── .babelrc ├── .circleci └── config.yml ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dist ├── module.js └── plugin.template.js ├── package-lock.json ├── package.json ├── src ├── module.js └── plugin.template.js └── test ├── fixture ├── nuxt.config.js └── pages │ └── index.vue └── module.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "minified": true, 3 | "sourceMaps": true, 4 | "presets": [ 5 | "es2015", 6 | "stage-3", 7 | "minify" 8 | ], 9 | "ignore": [ 10 | "src/plugin.template.js" 11 | ] 12 | } -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: /usr/src/app 5 | docker: 6 | - image: banian/node 7 | steps: 8 | # Checkout repository 9 | - checkout 10 | 11 | # Restore cache 12 | - restore_cache: 13 | key: yarn-{{ checksum "yarn.lock" }} 14 | 15 | # Install dependencies 16 | - run: 17 | name: Install Dependencies 18 | command: NODE_ENV=dev yarn 19 | 20 | # Keep cache 21 | - save_cache: 22 | key: yarn-{{ checksum "yarn.lock" }} 23 | paths: 24 | - "node_modules" 25 | 26 | # Test 27 | - run: 28 | name: Tests 29 | command: yarn test && yarn codecov 30 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_size = 2 6 | indent_style = space 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | src/templates 2 | src/*.template.* 3 | dist 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parserOptions: { 4 | sourceType: 'module' 5 | }, 6 | env: { 7 | browser: true, 8 | node: true, 9 | }, 10 | extends: [ 11 | 'airbnb', 12 | ], 13 | plugins: [ 14 | 'vue', 15 | ], 16 | rules: { 17 | // Allow paren-less arrow functions 18 | 'arrow-parens': 0, 19 | // Allow async-await 20 | 'generator-star-spacing': 0, 21 | // Allow debugger during development 22 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 23 | // Do not allow console.logs etc... 24 | 'no-console': 1, 25 | 'no-param-reassign': 0, 26 | }, 27 | globals: { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_STORE 8 | coverage 9 | dist 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) WilliamDASILVA 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nuxt Google Maps Module 2 | 3 | [![npm (scoped with tag)](https://img.shields.io/npm/v/nuxt-google-maps-module/latest.svg?style=flat-square)](https://npmjs.com/package/nuxt-google-maps-module) 4 | [![npm](https://img.shields.io/npm/dt/nuxt-google-maps-module.svg?style=flat-square)](https://npmjs.com/package/nuxt-google-maps-module) 5 | [![js-airbnb-style](https://img.shields.io/badge/code_style-airbnb-brightgreen.svg?style=flat-square)](https://github.com/airbnb/javascript) 6 | 7 | > A NuxtJS module to import Google maps script 8 | 9 | ## Table of Contents ## 10 | 11 | * [Requirements](#requirements) 12 | * [Install](#install) 13 | * [Getting Started](#getting-started) 14 | * [Usage](#usage) 15 | * [License](#license) 16 | 17 | ## Requirements 18 | 19 | * npm 20 | * NuxtJS 21 | * NodeJS 22 | 23 | ## Install 24 | 25 | ```bash 26 | $ npm install --save nuxt-google-maps-module 27 | ``` 28 | 29 | ## Getting Started 30 | 31 | Add `nuxt-google-maps-module` to `modules` section of `nuxt.config.js`. 32 | ```js 33 | { 34 | modules: [ 35 | // Simple usage 36 | 'nuxt-google-maps-module', 37 | 38 | // With options 39 | ['nuxt-google-maps-module', { 40 | /* module options */ 41 | key: 'GOOGLE MAPS KEY', // Default 42 | }], 43 | ] 44 | } 45 | ``` 46 | or even 47 | ```js 48 | { 49 | modules: [ 50 | 'nuxt-google-maps-module', 51 | ], 52 | maps: { 53 | key: 'GOOGLE MAPS KEY', 54 | }, 55 | } 56 | ``` 57 | 58 | ## Usage 59 | 60 | Once configured in `nuxt.config.js`, you can use it in your components like: 61 | 62 | ```js 63 | { 64 | ... 65 | mounted() { 66 | const autocomplete = new this.$google.maps.places.Autocomplete(inputElement, 67 | { 68 | types: ['geocode'], 69 | }, 70 | ); 71 | }, 72 | ... 73 | } 74 | ``` 75 | 76 | ## License 77 | 78 | [MIT License](./LICENSE) 79 | -------------------------------------------------------------------------------- /dist/module.js: -------------------------------------------------------------------------------- 1 | 'use strict';var _extends=Object.assign||function(a){for(var b,c=1;c { 21 | Object.defineProperty(Vue.prototype, '$google', { 22 | get() { 23 | return window.google; 24 | }, 25 | configurable: true, 26 | }); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-google-maps-module", 3 | "version": "1.6.0", 4 | "description": "NuxtJS module to import Google Maps", 5 | "license": "MIT", 6 | "contributors": [ 7 | { 8 | "name": "William DA SILVA " 9 | } 10 | ], 11 | "main": "dist/module.js", 12 | "repository": "https://github.com/WilliamDASILVA/nuxt-google-maps-module", 13 | "publishConfig": { 14 | "access": "public" 15 | }, 16 | "scripts": { 17 | "build": "babel src -d dist --copy-files", 18 | "lint": "eslint src test", 19 | "test": "ava test/*.test.js --serial --verbose", 20 | "release": "standard-version && git push --follow-tags && npm publish" 21 | }, 22 | "files": [ 23 | "dist" 24 | ], 25 | "dependencies": {}, 26 | "devDependencies": { 27 | "ava": "^0.24.0", 28 | "babel-cli": "^6.26.0", 29 | "babel-preset-env": "^1.6.1", 30 | "babel-preset-es2015": "^6.24.1", 31 | "babel-preset-minify": "^0.2.0", 32 | "babel-preset-stage-3": "^6.24.1", 33 | "eslint": "^4.14.0", 34 | "eslint-config-airbnb": "^16.1.0", 35 | "eslint-plugin-jest": "^21.7.0", 36 | "eslint-plugin-jsx-a11y": "^6.0.3", 37 | "har-validator": "^5.1.0", 38 | "jsdom": "^11.5.1", 39 | "nuxt": "^1.1.1", 40 | "nuxt-module-builder": "latest", 41 | "qs": "^6.5.1" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/module.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | 3 | module.exports = function module(moduleOptions) { 4 | const defaults = { 5 | defer: true, 6 | async: true, 7 | body: true, 8 | key: null, 9 | libraries: [ 10 | 'places', 11 | ], 12 | }; 13 | 14 | const options = { 15 | ...defaults, 16 | ...this.options.maps, 17 | ...moduleOptions, 18 | }; 19 | 20 | const libraries = options.libraries.join(','); 21 | 22 | /** 23 | * Make sure the initMap function is created in the DOM 24 | * before we even think to initialize the Google Maps API 25 | */ 26 | // eslint-disable-next-line 27 | this.options.head.__dangerouslyDisableSanitizers = ['script']; 28 | this.options.head.script.push({ 29 | innerHTML: `window.initMap = function(){ 30 | window.dispatchEvent(new Event('maps-module:loaded')); 31 | window.addEventListener('maps-module:initiated', function(){ 32 | setTimeout(function(){ 33 | window.dispatchEvent(new Event('maps-module:loaded')); 34 | }); 35 | }); 36 | }`, 37 | type: 'text/javascript', 38 | }); 39 | 40 | /** 41 | * Import the Google Maps script with initMap callback. 42 | */ 43 | this.options.head.script.push({ 44 | src: `//maps.googleapis.com/maps/api/js?key=${options.key}&libraries=${libraries}&callback=initMap`, 45 | defer: options.defer, 46 | async: options.async, 47 | }); 48 | 49 | /** 50 | * Inject the plugin to inject the Google object in the Vue instance 51 | */ 52 | this.addPlugin({ 53 | src: resolve(__dirname, './plugin.template.js'), 54 | options, 55 | }); 56 | }; 57 | 58 | // eslint-disable-next-line 59 | module.exports.meta = require(resolve(__dirname, './../package.json')); 60 | -------------------------------------------------------------------------------- /src/plugin.template.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | export default function (context, inject) { 4 | /** 5 | * Inject the Google object in the Nuxt instance, even if it's 6 | * not used server side. 7 | */ 8 | Vue['__nuxt_$google_installed__'] = true; 9 | inject('google', {}); 10 | 11 | /** 12 | * Apply the new Google object to the previously created one in our 13 | * Vue app (client side only) 14 | * Do an event boomerang to make sure the Google maps API callback was 15 | * called and google injected in Vue. 16 | */ 17 | if (typeof window !== 'undefined') { 18 | const event = new window.Event('maps-module:initiated'); 19 | window.dispatchEvent(event); 20 | window.addEventListener('maps-module:loaded', () => { 21 | Object.defineProperty(Vue.prototype, '$google', { 22 | get() { 23 | return window.google; 24 | }, 25 | configurable: true, 26 | }); 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/fixture/nuxt.config.js: -------------------------------------------------------------------------------- 1 | const { resolve } = require('path'); 2 | 3 | module.exports = { 4 | srcDir: __dirname, 5 | dev: false, 6 | render: { 7 | resourceHints: false, 8 | }, 9 | modules: [ 10 | [resolve(__dirname, './../../dist/module.js'), { 11 | }], 12 | ], 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixture/pages/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /test/module.test.js: -------------------------------------------------------------------------------- 1 | import test from 'ava'; 2 | import { Nuxt, Builder } from 'nuxt'; 3 | import { resolve } from 'path'; 4 | 5 | const port = 4000 || process.env.PORT; 6 | 7 | let nuxt; 8 | let config; 9 | 10 | // Create a NuxtJS instance before all the tests 11 | test.before(async (t) => { 12 | try { 13 | // eslint-disable-next-line 14 | config = require(resolve(__dirname, './fixture/nuxt.config.js')); 15 | } catch (e) { 16 | t.fail(e); 17 | } 18 | 19 | // config.modules.unshift(() => { 20 | // // Add test specific test only hooks on nuxt life cycle 21 | // }); 22 | 23 | nuxt = new Nuxt(config); 24 | await new Builder(nuxt).build(); 25 | await nuxt.listen(port); 26 | }); 27 | 28 | test.after(async () => { 29 | nuxt.close(); 30 | }); 31 | 32 | test('Render', async (t) => { 33 | t.pass(); 34 | }); 35 | --------------------------------------------------------------------------------