├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── generator ├── README.md ├── index.js └── templates │ ├── App_Resources │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── app.gradle │ │ ├── drawable-hdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-ldpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-mdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-nodpi │ │ │ └── splash_screen.xml │ │ ├── drawable-xhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-xxhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── drawable-xxxhdpi │ │ │ ├── background.png │ │ │ ├── icon.png │ │ │ └── logo.png │ │ ├── values-v21 │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ └── iOS │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── icon-1024.png │ │ │ ├── icon-29.png │ │ │ ├── icon-29@2x.png │ │ │ ├── icon-29@3x.png │ │ │ ├── icon-40.png │ │ │ ├── icon-40@2x.png │ │ │ ├── icon-40@3x.png │ │ │ ├── icon-60@2x.png │ │ │ ├── icon-60@3x.png │ │ │ ├── icon-76.png │ │ │ ├── icon-76@2x.png │ │ │ └── icon-83.5@2x.png │ │ ├── Contents.json │ │ ├── LaunchImage.launchimage │ │ │ ├── Contents.json │ │ │ ├── Default-1125h.png │ │ │ ├── Default-568h@2x.png │ │ │ ├── Default-667h@2x.png │ │ │ ├── Default-736h@3x.png │ │ │ ├── Default-Landscape-X.png │ │ │ ├── Default-Landscape.png │ │ │ ├── Default-Landscape@2x.png │ │ │ ├── Default-Landscape@3x.png │ │ │ ├── Default-Portrait.png │ │ │ ├── Default-Portrait@2x.png │ │ │ ├── Default.png │ │ │ └── Default@2x.png │ │ ├── LaunchScreen.AspectFill.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchScreen-AspectFill.png │ │ │ └── LaunchScreen-AspectFill@2x.png │ │ └── LaunchScreen.Center.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchScreen-Center.png │ │ │ └── LaunchScreen-Center@2x.png │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ └── build.xcconfig │ ├── nvw │ └── src │ │ ├── App.vue │ │ ├── assets │ │ └── logo.png │ │ ├── components │ │ ├── HelloWorld.android.vue │ │ ├── HelloWorld.ios.vue │ │ ├── HelloWorld.native.vue │ │ ├── HelloWorld.vue │ │ └── icon.png │ │ ├── main.js │ │ ├── main.native.js │ │ ├── package.json │ │ ├── router.js │ │ ├── styles │ │ ├── style-one.css │ │ ├── style-one.less │ │ ├── style-one.scss │ │ ├── style-one.styl │ │ ├── style-two.css │ │ ├── style-two.less │ │ ├── style-two.scss │ │ └── style-two.styl │ │ └── views │ │ ├── About.vue │ │ └── Home.vue │ ├── simple │ └── src │ │ ├── App.vue │ │ ├── assets │ │ └── logo.png │ │ ├── components │ │ ├── HelloWorld.android.vue │ │ ├── HelloWorld.ios.vue │ │ ├── HelloWorld.native.vue │ │ ├── HelloWorld.vue │ │ └── icon.png │ │ ├── main.js │ │ ├── main.native.js │ │ ├── package.json │ │ ├── router.js │ │ ├── styles │ │ ├── style-one.css │ │ ├── style-one.less │ │ ├── style-one.scss │ │ ├── style-one.styl │ │ ├── style-two.css │ │ ├── style-two.less │ │ ├── style-two.scss │ │ └── style-two.styl │ │ └── views │ │ ├── About.vue │ │ └── Home.vue │ └── vue-sfc-template.vue ├── index.js ├── lib ├── scripts │ └── webpack-maintenance.js └── tslint.js ├── logo.png ├── package-lock.json ├── package.json ├── prompts.js ├── tslint.json └── ui.js /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | generator/templates/ -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "root": true, 3 | "env": { 4 | "node": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:vue/recommended", 9 | "@vue/airbnb", 10 | "@vue/prettier" 11 | ], 12 | "rules": { 13 | "import/extensions": 0, 14 | "global-require": 0, 15 | "eol-last": 0, 16 | "no-param-reassign": 0, 17 | "object-curly-newline": 0, 18 | "no-plusplus": 0, 19 | "max-len": [ 20 | 2, 21 | { 22 | "code": 160 23 | } 24 | ], 25 | "prefer-destructuring": [ 26 | 2, 27 | { 28 | "object": true, 29 | "array": false 30 | } 31 | ] 32 | }, 33 | "parserOptions": { 34 | "parser": "babel-eslint" 35 | } 36 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .vscode -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | generator/templates/* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 160, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "tabWidth": 2, 6 | "semicolons": true, 7 | "bracketSpacing": true, 8 | "arrowParens": "always", 9 | "useTabs": false 10 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Igor Randjelovic 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 | # nativescript-vue-cli-plugin 2 | 3 | Nativescript-Vue Plugin for [vue-cli@3.0](https://github.com/vuejs/vue-cli) 4 | 5 | This plugin will integrate [Nativescript-Vue](https://nativescript-vue.org/) into new and existing Vue projects. Additionally, it will allow for the choice of developing for Native only environments or Native __and__ Web environments under a single project structure. In addition, choosing to integrate [Nativescript-Vue-Web](https://github.com/Nativescript-Vue-Web/Nativescript-Vue-Web), will allow for the development of Web components with a NativeScript-Vue like syntax that has the benefit of allowing for the sharing of components between the Native and Web sides of the project. This helps reduce the amount of code, maintenence needs, and the amount of time needed for development activities. 6 | 7 | ## Sharing logic in a single Web and Native capable component 8 | The key feature of this plugin is that it will allow you to compose SFC's that contain both Web and Native structures in them. If your component has exactly the same logic (` 43 | 48 | 53 | ``` 54 | 55 | ### Optional Separation of concerns for Web and Native SFC's 56 | If you want complete seperation of concerns between Web and Native for components, core logic and styling, you can also provide an alternate file naming scheme in your project. The name will dictate which mode (Web or Native) and platform (Android or IOS) the file will be used with. The same overall schema will work for `.vue`, `.js`, `.ts`, `.scss`, `.css`, `.styl`, and `.less` files. 57 | 58 | | File Type | Android __and__ IOS | Android only | IOS only | Web only | 59 | | ---------- | ------------------- | --------------- | --------------- | --------------- | 60 | | vue | *.native.vue | *.android.vue | *.ios.vue | *.vue | 61 | | js | *.native.js | *.android.js | *.ios.js | *.js | 62 | | ts | *.native.ts | *.android.ts | *.ios.ts | *.ts | 63 | | scss | *.native.scss | *.android.scss | *.ios.scss | *.scss | 64 | | css | *.native.css | *.android.css | *.ios.css | *.css | 65 | | stylus | *.native.styl | *.android.styl | *.ios.styl | *.styl | 66 | | less | *.native.less | *.android.less | *.ios.less | *.less | 67 | 68 | Webpack will handle figuring out which files to include based on the `npm run` command syntax you pass in. You can also mix and match this file naming schema with the `web` or `native` tag options mentioned above. 69 | 70 | At `serve` or `build` in conjunction with the mode such as `android` or `ios`, Webpack will filter which files are looked at. For instance, if you do `npm run serve:android`, then it will look for `*.native.vue` and `*.android.vue` files and ignore `*.ios.vue` files entirely. Conversely, it will do the same when you are working with `ios` and will ignore `*.android.vue` files. 71 | 72 | This will allow you to develop generic native components under the `*.native.vue` file extension, but in special cases, it may require you to do platform specific components, core logic and styling. Use the corrosponding file extension to allow this to happen. 73 | 74 | If you are building for web, then just `*.vue` will work and if you are building for a Native __only__ project, then `*.vue` will work as well as the previous options mentioned. 75 | 76 | ## Sharing components and assets between Native and Web SFC's 77 | If you want to use common components and assets between `web`, `android` and `ios`, you can do that. For `assets`, place them in `src/assets` and for components, place them in `src/components`. At compile time, assets will be copied to the output directory's `assets` folder and can be universally accessed across environments via something like `~/assets/logo.png`. For components, they can be universally accessed via something similar to `components/HelloWorld`. 78 | 79 | ## Install 80 | 81 | If vue-cli 3 is not yet installed, first follow the instructions here: https://github.com/vuejs/vue-cli 82 | 83 | **Tip**: If you don't want to overwrite your current vue-cli 2 setup because you still need `vue init`, [then try this](https://cli.vuejs.org/guide/creating-a-project.html#pulling-2-x-templates-legacy). 84 | 85 | Generate a project using vue-cli 3.0 86 | ```bash 87 | vue create my-app 88 | ``` 89 | 90 | Before installing the Nativescript-Vue CLI 3 Plugin, make sure to commit or stash changes in case you need to revert. 91 | 92 | To install the Nativescript-Vue CLI 3 Plugin... 93 | ```bash 94 | cd my-app 95 | vue add vue-cli-plugin-nativescript-vue 96 | ``` 97 | 98 | ## Invocation Prompts 99 | 1. Enter a unique application identifier 100 | * Accepting the default is fine for testing 101 | 2. Use HTML5 history mode? (Default: hash mode) 102 | * Required parameter for the cli core generator when vue-router is used 103 | 3. Is this a brand new project? (Default: Yes) 104 | * By choosing `No`, the plugin will try and be as non-destructive as possible to an existing project. It will do this by adding a folder into root named `ns-example` and add files into there to provide examples of how a project would change. 105 | * These changes will factor in answers to the other questions and adjust accordingly. Regardless of the answer, the plugin will install packages and adjust `package.json` as necessary to prep the project. 106 | 4. Dual Native AND Web development experience or a Native only? (Default: Dual) 107 | * By default, the plugin will assume you want to develop for the Web and Native environments within the same project. As such, there will be two sides to the project where web environments will be actively developed within `/src` and Native environments will be developed within `/app` unless you choose to integrate `Nativescript-Vue-Web` and all files will be placed in `/src`. 108 | * Warning: Choosing to develop for Native only will move the main entry point of the project and development folder to `/app`, it will copy the necessary files and then delete `/src`. 109 | * By choosing `Dual`, you will be able to bring your own component framework into the web portion of the project. `NativeScript-Vue` [cannot use vue-router](https://nativescript-vue.org/en/docs/routing/vue-router/) currently, so you will have to provide your own manual routing. The templated options deployed with the plugin will show how to do basic manual routing. 110 | 5. What type of template do you want to start with? (Default: Simple) 111 | * Simple is just a simple setup with a header and basic routing. 112 | * [Nativescript-Vue-Web](https://github.com/Nativescript-Vue-Web/Nativescript-Vue-Web) - The Simple template, but with NS-Vue like syntax for web components. This option should only appear if you have chosen to develop in the Dual Web and Native environments. This option will effecively integrate a web component framework that will allow you to develop components that can be used in the Web and Native side of the project. It uses `NativeScript-Vue` like syntax on components which will allow for the sharing of components between NativeScript and Web. 113 | * Sidebar (currently disabled), will allow you to start with a project that includes a fixed header and pop-out sidebar menu. 114 | * We expect to add more templates in the future as use cases come up. 115 | 116 | ## Running the project 117 | You will have several options in serving and building the project: 118 | 1. `npm run serve:web` 119 | 2. `npm run serve:android` 120 | 3. `npm run serve:ios` 121 | 4. `npm run build:web` 122 | 5. `npm run build:android` 123 | 6. `npm run build:ios` 124 | 125 | 126 | The basic `serve` and `build` options should be similar to what is in a CLI 3 project except the added options to dictate which kind of environment you are using: `web`, `android` or `ios`. Please note that when building web projects, they will output to `dist` and when building native projects, they will output to `platforms\android` or `platforms\ios` depending on which you are building at the time. 127 | 128 | ### Debugging your project 129 | You will have the standard options for debugging available to you as you would with just `tns`. You can do the following to debug Native versions of your app. 130 | 1. `npm run debug:android` 131 | 2. `npm run debug:ios` 132 | 133 | You should then be able to attach the Chrome debugger as you normally would via the [NativeScript docs](https://docs.nativescript.org/angular/tooling/debugging/chrome-devtools). 134 | 135 | You should also be able to debug directly in VSCode. The [NativeScript VSCode Extension docs](https://docs.nativescript.org/angular/tooling/visual-studio-code-extension) are a good place to start with understanding how to do this. However, you will need to modify your `launch.json` file to force `tns` to work properly with VUE CLI 3. 136 | 137 | Your `launch.json` file should look something like below. Notice the different in the `tnsArgs` line that is different than what is in the documentation link above. 138 | ```json 139 | { 140 | "version": "0.2.0", 141 | "configurations": [ 142 | { 143 | "name": "Launch on iOS", 144 | "type": "nativescript", 145 | "request": "launch", 146 | "platform": "ios", 147 | "appRoot": "${workspaceRoot}", 148 | "sourceMaps": true, 149 | "watch": true, 150 | "tnsArgs":[" --bundle --env.development cross-env-shell VUE_CLI_MODE=development.ios"] 151 | }, 152 | { 153 | "name": "Attach on iOS", 154 | "type": "nativescript", 155 | "request": "attach", 156 | "platform": "ios", 157 | "appRoot": "${workspaceRoot}", 158 | "sourceMaps": true, 159 | "watch": false 160 | }, 161 | { 162 | "name": "Launch on Android", 163 | "type": "nativescript", 164 | "request": "launch", 165 | "platform": "android", 166 | "appRoot": "${workspaceRoot}", 167 | "sourceMaps": true, 168 | "watch": true, 169 | "tnsArgs":[" --bundle --env.development cross-env-shell VUE_CLI_MODE=development.android"] 170 | }, 171 | { 172 | "name": "Attach on Android", 173 | "type": "nativescript", 174 | "request": "attach", 175 | "platform": "android", 176 | "appRoot": "${workspaceRoot}", 177 | "sourceMaps": true, 178 | "watch": false 179 | }, 180 | { 181 | "type": "chrome", 182 | "request": "launch", 183 | "name": "web: chrome", 184 | "url": "http://localhost:8080", 185 | "webRoot": "${workspaceFolder}/src", 186 | "breakOnLoad": true, 187 | "sourceMapPathOverrides": { 188 | "webpack:///src/*": "${webRoot}/*" 189 | } 190 | }, 191 | ] 192 | } 193 | ``` 194 | You will also need to modify your `vue.config.js` file to include a `webpack-chain` statement that will setup your source map. It should look something like this: 195 | ```js 196 | module.exports = { 197 | chainWebpack: config => { 198 | config 199 | .devtool('inline-source-map') 200 | } 201 | } 202 | ``` 203 | 204 | ### Previewing your Project 205 | You should be able to use the NativeScript Playground and Preview Apps via the following npm statements: 206 | 1. `npm run preview:android` 207 | 2. `npm run preview:ios` 208 | 209 | #### --env & --hmr command line recognition 210 | Basic support for passing the `env` command line option is in place, but has a slightly different syntax since we're working with the CLI 3 webpack infrastructure. To inject items into `env` at run-time, you will need to add `-- --env.option` Where option is one of the recognized options that Nativescript-Vue and this project supports. 211 | An example of this would be something like this: `npm run serve:android -- --env.production`. This would allow you to serve up a Production build of your Android app versus just running `npm run serve:android` which would serve a Development version of the same. 212 | 213 | HMR will also work by passing in `-- --hmr`. An example of this would be `npm run serve:android -- --hmr` 214 | 215 | #### Webpack related information 216 | The options passed in at `npm run` will dictate what webpack config is provided. The first choice webpack will make is if this is a `web` or `native` environment. Then, if it's a `native` environment, it will determine choices to be made between `ios` and `android`. 217 | 218 | Each time the project is built or served, the plugin will copy the latest webpack config from the cli to the root of your project. When you build a project, it will clean-up this file at the end, but just serving the project will not. This is an issue with [nativescript-dev-webpack](https://github.com/NativeScript/nativescript-dev-webpack) and cannot be overcome at this time. 219 | 220 | #### Inspecting the Webpack config 221 | If you'd like to see what the webpack config is doing then you can run one of the following: 222 | 223 | 1. `vue inspect -- --env.android > out-android.js` 224 | 2. `vue inspect -- --env.ios > out-ios.js` 225 | 3. `vue inspect -- --env.web > out-web.js` 226 | 227 | These will default to showing you the Development version of the webpack config. You can pass in the `-- --env.production` option to see the Production version of the config. Subtitute `development.android` or `production.ios`, etc to see the different configs based on the environmental variables. 228 | 229 | #### Aliases 230 | Prebuilt in the webpack config are several aliases that you can use. Here is a table listing out the various alias and the folder they use based on the environment chosen: 231 | 232 | | Alias | Native | Web | 233 | | ---------- | --------------- | --------------- | 234 | | ~ | /app | /src | 235 | | @ | /app | /src | 236 | | src | /src | /src | 237 | | assets | /src/assets | /src/assets | 238 | | components | /src/components | /src/components | 239 | | fonts | /src/fonts | /src/fonts | 240 | | styles | /src/styles | /src/styles | 241 | | root | / | / | 242 | 243 | 244 | ## For TypeScript enabled projects 245 | If your CLI 3 project has TypeScript enabled, then the plugin will attempt to give you a very basic TypeScript version of the template you choose. When you invoke the plugin and the template generator makes changes, you will notice the `*.d.ts` files that are usually in `src` will be moved to `/types`. The plugin's webpack integration will ensure these files are referenced correctly at compile and runtimes. 246 | -------------------------------------------------------------------------------- /generator/README.md: -------------------------------------------------------------------------------- 1 | # nativescript-vue-cli-plugin - Generator Readme 2 | 3 | Want to submit a PR for a new template? Read below. 4 | 5 | It is __highly, highly, highly suggested__ that you copy/paste the `simple` template in its entirety and then rename the copied directory. It will make it much easier for you to get started using the existing logic in the generator. Modifications to the existing generator logic will be considered for PR, but will have to go through rigourous testing to ensure the changes do not break all pre-existing templates. 6 | 7 | If you want to add additional templates to the plugin, then here's the information on how to do it: 8 | 9 | 1. Create a new option to the prompt question #5 concerning which template you'd like to deploy. 10 | * The value for the template should be kept simple and easy. 11 | 2. Create a new directory under `/generator/templates`. 12 | * The directory name should __exactly match__ the value from #1. For example if the value from #1 is `simple`, then the directory structure would be `/generator/templates/simple` 13 | 3. The new template directory __must__ have a single first-level subdirectory named `src`. 14 | 4. Inside the `src` directory, you should add the following in an effort to give the template feature consistancy to the other templates: 15 | * router.js 16 | * main.js 17 | * main.native.js (the NS-Vue project entry point) 18 | * package.json (this is the standard NativeScript-Vue package.json file. Just copy/paste from the simple template) 19 | * App.vue 20 | * views/About.vue (optional) 21 | * views/Home.vue (optional) 22 | * components/HelloWorld.vue (optional) 23 | * components/HelloWorld.native.vue (optional) 24 | * components/HelloWorld.ios.vue (optional) 25 | * components/HelloWorld.android.vue (optional) 26 | * assets/logo.png (optional, but highly encouraged to prove images are loading) 27 | 28 | Within the \*.vue files you will find [ejs](https://github.com/mde/ejs) syntax that will enable you to differentiate between TypeScript and non-TypeScript projects. Any new templates added to the project __must__ demonstrate they work across these options or the PR to add the template will be rejected. 29 | 30 | ### Word of warning concerning using EJS templates with Prettier 31 | Prettier does not support EJS templates and if you have Prettier automatically fix all issues in a `*.vue` template file, then you will run the risk of it overwriting sections of the template from one `if` statement to the `else` side of the statement. Pay close attention to this specifically in your `script` tags as it relates to the TypeScript vs. non-TypeScript parts of the template. Whichever one comes first in the `if` statement will overwrite the section after the `else` statement. 32 | 33 | -------------------------------------------------------------------------------- /generator/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | const path = require('path'); 4 | const fs = require('fs-extra'); 5 | const replace = require('replace-in-file'); 6 | 7 | const newline = process.platform === 'win32' ? '\r\n' : '\n'; 8 | 9 | module.exports = async (api, options, rootOptions) => { 10 | const genConfig = { 11 | // if it is a new project changes will be written as they normally would with any plugin 12 | // if it is an existing project, changes will be added to the ./ns-example directory 13 | dirPathPrefix: options.isNewProject === true ? './' : './ns-example/', 14 | 15 | // simple typescript detection and then variable is passed to multiple templating functions 16 | // to simply change the file's extension 17 | jsOrTs: api.hasPlugin('typescript') ? '.ts' : '.js', 18 | 19 | // A template type of 'simple' project will have a base template path that equals: ./templates/simple 20 | // then we determine if the project is using Nativescript-Vue-Web and we append a subdirectory to the base path 21 | templateTypePathModifer: options.templateType, 22 | 23 | // Get the location to the native app directory 24 | nativeAppPathModifier: options.isNativeOnly ? 'app/' : 'src/', 25 | 26 | // Determine the path to App_Resources 27 | get appResourcesPathModifier() { 28 | return this.nativeAppPathModifier + 'App_Resources'; 29 | }, 30 | 31 | // setup directories to exclude in the tsconfig.json file(s) 32 | get tsExclusionArray() { 33 | return ['node_modules', 'dist', 'platforms', 'hooks', this.appResourcesPathModifier]; 34 | } 35 | }; 36 | 37 | // common render options to be passed to render functions 38 | const commonRenderOptions = { 39 | applicationName: api.generator.pkg.name, 40 | applicationVersion: api.generator.pkg.version, 41 | applicationAndroidVersionCode: api.generator.pkg.version.split('.').join('0'), 42 | applicationDescription: api.generator.pkg.description || api.generator.pkg.name, 43 | applicationLicense: api.generator.pkg.license || 'MIT', 44 | applicationId: options.applicationId, 45 | historyMode: options.historyMode, 46 | doesCompile: api.hasPlugin('babel') || api.hasPlugin('typescript') ? true : false, 47 | usingBabel: api.hasPlugin('babel') ? true : false, 48 | usingTS: api.hasPlugin('typescript') ? true : false 49 | }; 50 | 51 | console.log('adding to package.json'); 52 | 53 | api.extendPackage({ 54 | nativescript: { 55 | id: 'org.nativescript.application', 56 | 'tns-android': { 57 | version: '6.3.1' 58 | }, 59 | 'tns-ios': { 60 | version: '6.3.0' 61 | } 62 | }, 63 | scripts: { 64 | 'build:android': 'npm run setup-webpack-config && tns build android --env.production && npm run remove-webpack-config', 65 | 'build:ios': 'npm run setup-webpack-config && tns build ios --env.production && npm run remove-webpack-config', 66 | 'remove-webpack-config': 'node ./node_modules/vue-cli-plugin-nativescript-vue/lib/scripts/webpack-maintenance post', 67 | 'serve:android': 'npm run setup-webpack-config && tns run android --env.development', 68 | 'serve:ios': 'npm run setup-webpack-config && tns run ios --env.development', 69 | // 'inspect:android': 'npm run setup-webpack-config && vue inspect -- --env.android > out-android.js', 70 | // 'inspect:ios': 'npm run setup-webpack-config && vue inspect -- --env.ios > out-ios.js', 71 | 'debug:android': 'npm run setup-webpack-config && tns debug android --env.development', 72 | 'debug:ios': 'npm run setup-webpack-config && tns debug ios --env.development', 73 | 'preview:android': 'npm run setup-webpack-config && tns preview --env.development --env.android', 74 | 'preview:ios': 'npm run setup-webpack-config && tns preview --env.development --env.ios', 75 | 'setup-webpack-config': 'node ./node_modules/vue-cli-plugin-nativescript-vue/lib/scripts/webpack-maintenance pre', 76 | 'clean:platforms': 'rimraf platforms', 77 | 'clean:android': 'rimraf platforms/android', 78 | 'clean:ios': 'rimraf platforms/ios' 79 | }, 80 | dependencies: { 81 | 'nativescript-vue': '^2.5.0-alpha.3', 82 | 'tns-core-modules': '^6.3.2' 83 | }, 84 | devDependencies: { 85 | 'nativescript-dev-webpack': '^1.4.0', 86 | 'nativescript-vue-template-compiler': '^2.5.0-alpha.3', 87 | 'nativescript-worker-loader': '~0.9.5', 88 | 'node-sass': '^4.12.0', 89 | 'string-replace-loader': '^2.2.0', 90 | rimraf: '^2.6.3' 91 | // webpack: '4.28.4', 92 | // 'webpack-cli': '^3.3.2' 93 | } 94 | }); 95 | 96 | // add scripts when we are also developing for the web 97 | if (!options.isNativeOnly) { 98 | api.extendPackage({ 99 | scripts: { 100 | 'serve:web': 'vue-cli-service serve --mode development.web', 101 | 'build:web': 'vue-cli-service build --mode production.web' 102 | //'inspect:web': 'npm run setup-webpack-config && vue inspect -- --env.web > out-web.js' 103 | } 104 | }); 105 | 106 | // if we are using NativeScript-Vue-Web then add the package 107 | if (options.templateType == 'nvw') { 108 | api.extendPackage({ 109 | dependencies: { 110 | 'nativescript-vue-web': '^0.9.4' 111 | } 112 | }); 113 | } 114 | } else { 115 | // 116 | } 117 | 118 | if (rootOptions.router) { 119 | api.extendPackage({ 120 | dependencies: { 121 | 'nativescript-vue-navigator': '^0.2.0' 122 | } 123 | }); 124 | } 125 | 126 | if (api.hasPlugin('typescript')) { 127 | api.extendPackage({ 128 | dependencies: {}, 129 | devDependencies: { 130 | 'fork-ts-checker-webpack-plugin': '^1.5.0', 131 | 'terser-webpack-plugin': '^2.1.3', 132 | 'tns-platform-declarations': '^6.3.2' 133 | } 134 | }); 135 | 136 | // this means it's a typescript project and using babel 137 | if (api.hasPlugin('babel')) { 138 | api.extendPackage({ 139 | dependencies: {}, 140 | devDependencies: { 141 | '@babel/types': '^7.4.4' 142 | } 143 | }); 144 | } 145 | } 146 | 147 | // if the project is using babel, then load appropriate packages 148 | if (api.hasPlugin('babel')) { 149 | api.extendPackage({ 150 | devDependencies: { 151 | '@babel/core': '^7.5.5', 152 | '@babel/preset-env': '^7.5.5', 153 | 'babel-loader': '^8.0.6', 154 | '@babel/traverse': '^7.5.5' 155 | } 156 | }); 157 | 158 | api.render(async () => { 159 | fs.ensureFileSync(genConfig.dirPathPrefix + 'babel.config.js'); 160 | await applyBabelConfig(api, genConfig.dirPathPrefix + 'babel.config.js'); 161 | }); 162 | } 163 | 164 | // if the project is using eslint, add some global variables 165 | // to the eslintConfig in order to avoid no-def errors 166 | if (api.hasPlugin('eslint')) { 167 | api.extendPackage({ 168 | eslintConfig: { 169 | globals: { 170 | TNS_APP_MODE: true, 171 | TNS_APP_PLATFORM: true 172 | } 173 | } 174 | }); 175 | } 176 | 177 | console.log('deleting from package.json'); 178 | api.extendPackage((pkg) => { 179 | // if the project is using babel, then delete babel-core 180 | if (api.hasPlugin('babel')) { 181 | delete pkg.devDependencies['babel-core']; 182 | } 183 | // we will be replacing these 184 | delete pkg.scripts['serve'], delete pkg.scripts['build']; 185 | 186 | if (options.isNativeOnly) { 187 | delete pkg.browserslist; 188 | } 189 | 190 | if (options.templateType !== 'nvw') { 191 | delete pkg.dependencies['nativescript-vue-web']; 192 | } 193 | }); 194 | 195 | console.log('doing template rendering'); 196 | 197 | // render App_Resources folder 198 | api.render(async () => { 199 | // eslint-disable-next-line prettier/prettier 200 | await renderDirectoryStructure( 201 | api, 202 | options, 203 | rootOptions, 204 | '.js', 205 | commonRenderOptions, 206 | './templates/App_Resources', 207 | genConfig.dirPathPrefix + genConfig.appResourcesPathModifier 208 | ); 209 | }); 210 | 211 | // If Native only or Dual Native and Web Project. 212 | if (!options.isNativeOnly) { 213 | api.render(async () => { 214 | // render src directory 215 | await renderDirectoryStructure( 216 | api, 217 | options, 218 | rootOptions, 219 | genConfig.jsOrTs, 220 | commonRenderOptions, 221 | path.join('templates', genConfig.templateTypePathModifer, 'src'), 222 | genConfig.dirPathPrefix + 'src' 223 | ); 224 | 225 | // add router statements to src/main.*s 226 | await vueRouterSetup(api, genConfig.dirPathPrefix, genConfig.jsOrTs); 227 | 228 | // add vuex statements to src/main.*s 229 | await vuexSetup(api, options, genConfig.dirPathPrefix, genConfig.jsOrTs, genConfig.nativeAppPathModifier); 230 | }); 231 | } else { 232 | // Is Native Only 233 | api.render(async () => { 234 | // render app directory 235 | await renderDirectoryStructure( 236 | api, 237 | options, 238 | rootOptions, 239 | genConfig.jsOrTs, 240 | commonRenderOptions, 241 | path.join('templates', genConfig.templateTypePathModifer, 'src'), 242 | genConfig.dirPathPrefix + genConfig.nativeAppPathModifier.slice(0, -1) 243 | ); 244 | 245 | // add vuex statements to app/main.*s 246 | await vuexSetup(api, options, genConfig.dirPathPrefix, genConfig.jsOrTs); 247 | }); 248 | } 249 | 250 | api.onCreateComplete(async () => { 251 | // make changes to .gitignore 252 | gitignoreAdditions(api); 253 | 254 | // create files in ./ or ./ns-example 255 | writeRootFiles(api, options, genConfig.dirPathPrefix); 256 | 257 | // create nsconfig.json in ./ or ./ns-example 258 | nsconfigSetup(genConfig.dirPathPrefix, api.resolve('nsconfig.json'), genConfig.nativeAppPathModifier, genConfig.appResourcesPathModifier, options); 259 | 260 | // copy over .vue with native.vue files 261 | if (options.isNativeOnly) { 262 | nativeOnlyRenameFiles(genConfig.dirPathPrefix + genConfig.nativeAppPathModifier.slice(0, -1)); 263 | } 264 | 265 | // remove router config for projects that don't use vue-router 266 | if (!rootOptions.router) { 267 | fs.remove(genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'router' + genConfig.jsOrTs, (err) => { 268 | if (err) throw err; 269 | }); 270 | } 271 | 272 | if (api.hasPlugin('typescript')) { 273 | // we need to edit the tsconfig.json file in /app 274 | // for a Native only project to remove references to /src 275 | await tsconfigSetup(options, genConfig.dirPathPrefix, genConfig.nativeAppPathModifier); 276 | 277 | if (fs.existsSync(api.resolve('tslint.json'))) { 278 | await tslintSetup(genConfig.dirPathPrefix, api.resolve('tslint.json'), genConfig.tsExclusionArray); 279 | 280 | const baseDir = genConfig.nativeAppPathModifier; 281 | require('../lib/tslint')( 282 | { 283 | _: [`${baseDir}**/*.ts`, `${baseDir}**/*.vue`, `${baseDir}**/*.tsx`, 'tests/**/*.ts', 'tests/**/*.tsx'] 284 | }, 285 | api, 286 | false 287 | ); 288 | } 289 | } 290 | 291 | // the main difference between New and Existing for this section is 292 | // that for New projects we are moving files around, but for 293 | // existing projects we are copying files into ./ns-example 294 | if (options.isNewProject) { 295 | // move type files out of src to ./ or ./ns-example 296 | if (api.hasPlugin('typescript')) { 297 | // Do these synchronously so in the event we delete the ./src directory in a native only 298 | // situation below we don't try and move a file that no longer exists 299 | try { 300 | fs.moveSync('./src/shims-tsx.d.ts', genConfig.dirPathPrefix + 'types/shims-tsx.d.ts', { overwrite: true }); 301 | fs.moveSync('./src/shims-vue.d.ts', genConfig.dirPathPrefix + 'types/shims-vue.d.ts', { overwrite: true }); 302 | } catch (err) { 303 | throw err; 304 | } 305 | } 306 | 307 | // for new projects that are native only, move files/dirs and delete others 308 | if (options.isNativeOnly) { 309 | // Do these synchronously so that when we delete the ./src directory below 310 | // we don't try and move a file that no longer exists 311 | try { 312 | // move store.js file from ./src to ./app 313 | if (api.hasPlugin('vuex')) { 314 | fs.moveSync('./src/store' + genConfig.jsOrTs, genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'store' + genConfig.jsOrTs, { 315 | overwrite: true 316 | }); 317 | } 318 | } catch (err) { 319 | throw err; 320 | } 321 | // remove src directory as we don't need it any longer 322 | fs.remove('./src', (err) => { 323 | if (err) throw err; 324 | }); 325 | // remove public directory as we don't need it any longer 326 | fs.remove('./public', (err) => { 327 | if (err) throw err; 328 | }); 329 | // rename main.native.js to main.js 330 | fs.moveSync( 331 | genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'main.native' + genConfig.jsOrTs, 332 | genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'main' + genConfig.jsOrTs, 333 | { 334 | overwrite: true 335 | } 336 | ); 337 | 338 | nativeOnlyPackageJsonSetup(genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'package.json'); 339 | } 340 | } else if (!options.isNewProject) { 341 | // copy type files from ./src to ./ns-example 342 | if (api.hasPlugin('typescript')) { 343 | fs.copy('./src/shims-tsx.d.ts', path.join(genConfig.dirPathPrefix, 'types/shims-tsx.d.ts'), (err) => { 344 | if (err) throw err; 345 | }); 346 | 347 | fs.copy('./src/shims-vue.d.ts', path.join(genConfig.dirPathPrefix, 'types/shims-vue.d.ts'), (err) => { 348 | if (err) throw err; 349 | }); 350 | } 351 | 352 | if (options.isNativeOnly) { 353 | // move store.js file from ./src to ./ns-example/app 354 | if (api.hasPlugin('vuex')) { 355 | fs.copy('./src/store' + genConfig.jsOrTs, genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'store' + genConfig.jsOrTs, (err) => { 356 | if (err) throw err; 357 | }); 358 | } 359 | 360 | // rename main.native.js to main.js 361 | fs.moveSync( 362 | genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'main.native' + genConfig.jsOrTs, 363 | genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'main' + genConfig.jsOrTs, 364 | { 365 | overwrite: true 366 | } 367 | ); 368 | 369 | nativeOnlyPackageJsonSetup(genConfig.dirPathPrefix + genConfig.nativeAppPathModifier + 'package.json'); 370 | } 371 | } else { 372 | // nothing to do here 373 | } 374 | }); 375 | }; 376 | 377 | // setup vue-router options 378 | // will not setup any vue-router options for native app 379 | // for new projects it will write to changes as normal 380 | // and for existing projects it will write changes to the ./ns-example directory 381 | const vueRouterSetup = (module.exports.vueRouterSetup = async (api, filePathPrefix, jsOrTs) => { 382 | try { 383 | if (api.hasPlugin('vue-router')) { 384 | api.injectImports(filePathPrefix.replace(/.\//, '') + 'src/main' + jsOrTs, `import router from './router';`); 385 | api.injectRootOptions(filePathPrefix.replace(/.\//, '') + 'src/main' + jsOrTs, `router`); 386 | } 387 | } catch (err) { 388 | throw err; 389 | } 390 | }); 391 | 392 | // setup Vuex options 393 | // for new projects it will write to changes as normal 394 | // and for existing projects it will write changes to the ./ns-example directory 395 | const vuexSetup = (module.exports.vuexSetup = async (api, options, filePathPrefix, jsOrTs, nativeAppPathModifier) => { 396 | try { 397 | if (api.hasPlugin('vuex')) { 398 | if (!options.isNativeOnly) { 399 | api.injectImports(filePathPrefix.replace(/.\//, '') + 'src/main' + jsOrTs, `import store from './store';`); 400 | api.injectRootOptions(filePathPrefix.replace(/.\//, '') + 'src/main' + jsOrTs, `store`); 401 | 402 | // if we're using Nativescript-Vue-Web, then we have to modify the main.native file 403 | api.injectImports(filePathPrefix.replace(/.\//, '') + 'src/main.native' + jsOrTs, `import store from './store';`); 404 | api.injectRootOptions(filePathPrefix.replace(/.\//, '') + 'src/main.native' + jsOrTs, `store`); 405 | } else { 406 | // if it's native only, it will not do anything in /src directory 407 | api.injectImports(filePathPrefix.replace(/.\//, '') + nativeAppPathModifier + 'main' + jsOrTs, `import store from './store';`); 408 | api.injectRootOptions(filePathPrefix.replace(/.\//, '') + nativeAppPathModifier + 'main' + jsOrTs, `store`); 409 | } 410 | } 411 | } catch (err) { 412 | throw err; 413 | } 414 | }); 415 | 416 | // write out babel.config.js options by adding options and replacing the base @vue/app 417 | // for new projects it will write to the root of the project 418 | // and for existing projects it will write it to the ./ns-example directory 419 | const applyBabelConfig = (module.exports.applyBabelConfig = async (api, filePath) => { 420 | const babelReplaceOptions = { 421 | files: '', 422 | from: " '@vue/app'", 423 | to: " process.env.VUE_PLATFORM === 'web' ? '@vue/app' : {}, " + newline + " ['@babel/env', { targets: { esmodules: true } }]" 424 | }; 425 | 426 | try { 427 | babelReplaceOptions.files = filePath; 428 | 429 | api.render((files) => { 430 | files[filePath] = api.genJSConfig({ 431 | plugins: ['@babel/plugin-syntax-dynamic-import'], 432 | presets: ['@vue/app'] 433 | }); 434 | // eslint-disable-next-line no-unused-vars 435 | replace(babelReplaceOptions, (err, changes) => { 436 | if (err) throw err; 437 | }); 438 | }); 439 | } catch (err) { 440 | throw err; 441 | } 442 | }); 443 | 444 | // write out files in the root of the project 445 | // this includes the environment files as well as a global types file for 446 | // Typescript projects. for new projects it will write files to the root of the project 447 | // and for existing projects it will write it to the ./ns-example directory 448 | const writeRootFiles = (module.exports.writeRootFiles = async (api, options, filePathPrefix) => { 449 | try { 450 | const envDevelopmentAndroid = 'NODE_ENV=development' + newline + 'VUE_APP_PLATFORM=android' + newline + 'VUE_APP_MODE=native'; 451 | const envDevelopmentIOS = 'NODE_ENV=development' + newline + 'VUE_APP_PLATFORM=ios' + newline + 'VUE_APP_MODE=native'; 452 | const envProductionAndroid = 'NODE_ENV=production' + newline + 'VUE_APP_PLATFORM=android' + newline + 'VUE_APP_MODE=native'; 453 | const envProductionIOS = 'NODE_ENV=production' + newline + 'VUE_APP_PLATFORM=ios' + newline + 'VUE_APP_MODE=native'; 454 | 455 | fs.writeFileSync( 456 | filePathPrefix + '.env.development.android', 457 | envDevelopmentAndroid, 458 | { 459 | encoding: 'utf8' 460 | }, 461 | (err) => { 462 | if (err) throw err; 463 | } 464 | ); 465 | fs.writeFileSync( 466 | filePathPrefix + '.env.development.ios', 467 | envDevelopmentIOS, 468 | { 469 | encoding: 'utf8' 470 | }, 471 | (err) => { 472 | if (err) throw err; 473 | } 474 | ); 475 | fs.writeFileSync( 476 | filePathPrefix + '.env.production.android', 477 | envProductionAndroid, 478 | { 479 | encoding: 'utf8' 480 | }, 481 | (err) => { 482 | if (err) throw err; 483 | } 484 | ); 485 | fs.writeFileSync( 486 | filePathPrefix + '.env.production.ios', 487 | envProductionIOS, 488 | { 489 | encoding: 'utf8' 490 | }, 491 | (err) => { 492 | if (err) throw err; 493 | } 494 | ); 495 | 496 | // only write these out if we are also developing for the web 497 | if (!options.isNativeOnly) { 498 | console.log('dual components env files'); 499 | const envDevelopmentWeb = 'NODE_ENV=development' + newline + 'VUE_APP_PLATFORM=web' + newline + 'VUE_APP_MODE=web'; 500 | const envProductionWeb = 'NODE_ENV=production' + newline + 'VUE_APP_PLATFORM=web' + newline + 'VUE_APP_MODE=web'; 501 | 502 | fs.writeFileSync( 503 | filePathPrefix + '.env.development.web', 504 | envDevelopmentWeb, 505 | { 506 | encoding: 'utf8' 507 | }, 508 | (err) => { 509 | if (err) throw err; 510 | } 511 | ); 512 | fs.writeFileSync( 513 | filePathPrefix + '.env.production.web', 514 | envProductionWeb, 515 | { 516 | encoding: 'utf8' 517 | }, 518 | (err) => { 519 | if (err) throw err; 520 | } 521 | ); 522 | } 523 | 524 | // only write this out if we are using typescript 525 | if (api.hasPlugin('typescript')) { 526 | // this file is ultimately optional if you don't use any process.env.VARIABLE_NAME references in your code 527 | const globalTypes = 528 | 'declare const TNS_ENV: string;' + newline + 'declare const TNS_APP_PLATFORM: string;' + newline + 'declare const TNS_APP_MODE: string;'; 529 | fs.outputFileSync( 530 | filePathPrefix + 'types/globals.d.ts', 531 | globalTypes, 532 | { 533 | encoding: 'utf8' 534 | }, 535 | (err) => { 536 | if (err) throw err; 537 | } 538 | ); 539 | } 540 | } catch (err) { 541 | throw err; 542 | } 543 | }); 544 | 545 | // write .gitignore additions for native app exemptions 546 | // will make changes to the root .gitignore file regardless of new or exisiting project 547 | const gitignoreAdditions = (module.exports.gitignoreAdditions = async (api) => { 548 | try { 549 | let gitignoreContent; 550 | const gitignorePath = api.resolve('.gitignore'); 551 | const gitignoreAdditions = newline + '# NativeScript application' + newline + 'hooks' + newline + 'platforms' + newline + 'webpack.config.js'; 552 | 553 | if (fs.existsSync(gitignorePath)) { 554 | gitignoreContent = fs.readFileSync(gitignorePath, { 555 | encoding: 'utf8' 556 | }); 557 | } else { 558 | gitignoreContent = ''; 559 | } 560 | 561 | if (gitignoreContent.indexOf(gitignoreAdditions) === -1) { 562 | gitignoreContent += gitignoreAdditions; 563 | 564 | fs.writeFileSync( 565 | gitignorePath, 566 | gitignoreContent, 567 | { 568 | encoding: 'utf8' 569 | }, 570 | (err) => { 571 | if (err) throw err; 572 | } 573 | ); 574 | } 575 | } catch (err) { 576 | throw err; 577 | } 578 | }); 579 | 580 | // setup nsconfig.json file. for new projects it will write to the root of the project 581 | // and for existing projects it will write it to the ./ns-example directory 582 | const nsconfigSetup = (module.exports.nsconfigSetup = async (dirPathPrefix, nsconfigPath, nativeAppPathModifier, appResourcesPathModifier, options) => { 583 | let nsconfigContent = ''; 584 | 585 | try { 586 | if (fs.existsSync(nsconfigPath)) { 587 | nsconfigContent = JSON.parse( 588 | fs.readFileSync(nsconfigPath, { 589 | encoding: 'utf8' 590 | }) 591 | ); 592 | } else { 593 | nsconfigContent = {}; 594 | } 595 | 596 | nsconfigContent.appPath = nativeAppPathModifier.slice(0, -1); 597 | nsconfigContent.appResourcesPath = appResourcesPathModifier; 598 | 599 | if (options.isNewProject) { 600 | nsconfigContent.useLegacyWorkflow = false; 601 | } 602 | 603 | fs.writeFileSync( 604 | dirPathPrefix + 'nsconfig.json', 605 | JSON.stringify(nsconfigContent, null, 2), 606 | { 607 | encoding: 'utf8' 608 | }, 609 | (err) => { 610 | if (err) console.error(err); 611 | } 612 | ); 613 | } catch (err) { 614 | throw err; 615 | } 616 | }); 617 | 618 | // can be used to strip out template tags in native only project 619 | // currently unused in preference for EJS templating 620 | // eslint-disable-next-line no-unused-vars 621 | const stripTemplateTags = (module.exports.stripTemplateTags = async (srcPathPrefix) => { 622 | try { 623 | const files = await getAllFilesInDirStructure(srcPathPrefix, ''); 624 | 625 | for (const file of files) { 626 | if (file.slice(-4) == '.vue') { 627 | const options = { 628 | files: path.join(srcPathPrefix, file), 629 | from: [ 630 | new RegExp(`^(()[\\s\\S]*?(<\\/template>)`, `gim`), 631 | new RegExp(`^(()`, `gim`) 632 | ], 633 | to: ['', ''] 634 | }; 635 | 636 | await replaceInFile(options); 637 | } 638 | } 639 | } catch (err) { 640 | throw err; 641 | } 642 | }); 643 | 644 | const nativeOnlyRenameFiles = (module.exports.nativeOnlyRenameFiles = async (srcPathPrefix) => { 645 | try { 646 | const _files = await getAllFilesInDirStructure(srcPathPrefix, ''); 647 | const files = new Array(); 648 | const match = '.native.vue'; 649 | 650 | for (const file of _files) { 651 | if (file.slice(-11) == match) { 652 | files.push(path.join(srcPathPrefix, file)); 653 | } 654 | } 655 | 656 | for (const file of files) { 657 | const oldFile = file.replace(match, '.vue'); 658 | fs.moveSync(file, oldFile, { overwrite: true }); 659 | } 660 | } catch (err) { 661 | throw err; 662 | } 663 | }); 664 | 665 | // setup tslintSetup 666 | const nativeOnlyPackageJsonSetup = (module.exports.nativeOnlyPackageJsonSetup = async (filePath) => { 667 | let fileContents = ''; 668 | 669 | try { 670 | if (fs.existsSync(filePath)) { 671 | fileContents = JSON.parse( 672 | fs.readFileSync(filePath, { 673 | encoding: 'utf8' 674 | }) 675 | ); 676 | } else { 677 | return; 678 | } 679 | 680 | fileContents.main = 'main'; 681 | 682 | fs.writeFileSync( 683 | filePath, 684 | JSON.stringify(fileContents, null, 2), 685 | { 686 | encoding: 'utf8' 687 | }, 688 | (err) => { 689 | if (err) console.error(err); 690 | } 691 | ); 692 | } catch (err) { 693 | throw err; 694 | } 695 | }); 696 | 697 | // setup tslintSetup 698 | const tslintSetup = (module.exports.tslintSetup = async (dirPathPrefix, tslintPath, tsExclusionArray) => { 699 | let tslintContent = ''; 700 | 701 | try { 702 | if (fs.existsSync(tslintPath)) { 703 | tslintContent = JSON.parse( 704 | fs.readFileSync(tslintPath, { 705 | encoding: 'utf8' 706 | }) 707 | ); 708 | } else { 709 | return; 710 | } 711 | 712 | // create arrays if they aren't already in tslint.json 713 | if (tslintContent.linterOptions.exclude === undefined) tslintContent.linterOptions.exclude = new Array(); 714 | if (tslintContent.exclude === undefined) tslintContent.exclude = new Array(); 715 | 716 | // add items into exclude arrays, but only if they don't already exist 717 | for (let item of tsExclusionArray) { 718 | if (!tslintContent.linterOptions.exclude.includes(item + '/**')) tslintContent.linterOptions.exclude.push(item + '/**'); 719 | 720 | if (!tslintContent.exclude.includes(item)) tslintContent.exclude.push(item); 721 | } 722 | 723 | fs.writeFileSync( 724 | dirPathPrefix + 'tslint.json', 725 | JSON.stringify(tslintContent, null, 2), 726 | { 727 | encoding: 'utf8' 728 | }, 729 | (err) => { 730 | if (err) console.error(err); 731 | } 732 | ); 733 | } catch (err) { 734 | throw err; 735 | } 736 | }); 737 | 738 | // setup tsconfig for native only projects 739 | const tsconfigSetup = (module.exports.tsconfigSetup = async (options, dirPathPrefix, nativeAppPathModifier) => { 740 | try { 741 | // setup the ability to edit the tsconfig.json file in the root of the project 742 | let tsConfigContent = ''; 743 | let tsConfigPath = path.join(dirPathPrefix, 'tsconfig.json'); 744 | 745 | if (fs.existsSync(tsConfigPath)) { 746 | tsConfigContent = fs.readJsonSync(tsConfigPath, { 747 | encoding: 'utf8' 748 | }); 749 | } else { 750 | return; 751 | } 752 | 753 | tsConfigContent.compilerOptions.noImplicitAny = false; 754 | // // // tsConfigContent.compilerOptions.types = []; 755 | 756 | // edit types attribute to fix build 757 | tsConfigContent.compilerOptions.types = ['node']; 758 | 759 | // edit some of the options in compilerOptions.paths object array 760 | tsConfigContent.compilerOptions.paths['@/*'] = [nativeAppPathModifier + '*']; 761 | tsConfigContent.compilerOptions.paths['assets/*'] = [nativeAppPathModifier + 'assets/*']; 762 | tsConfigContent.compilerOptions.paths['fonts/*'] = [nativeAppPathModifier + 'fonts/*']; 763 | tsConfigContent.compilerOptions.paths['components/*'] = [nativeAppPathModifier + 'components/*']; 764 | tsConfigContent.compilerOptions.paths['styles/*'] = [nativeAppPathModifier + 'styles/*']; 765 | 766 | // add the types directory into the config 767 | if (!tsConfigContent.include.includes('types/**/*.d.ts')) tsConfigContent.include.push('types/**/*.d.ts'); 768 | 769 | // add items into the include array 770 | if (!tsConfigContent.include.includes(nativeAppPathModifier + '**/*.ts')) tsConfigContent.include.push(nativeAppPathModifier + '**/*.ts'); 771 | if (!tsConfigContent.include.includes(nativeAppPathModifier + '**/*.tsx')) tsConfigContent.include.push(nativeAppPathModifier + '**/*.tsx'); 772 | if (!tsConfigContent.include.includes(nativeAppPathModifier + '**/*.vue')) tsConfigContent.include.push(nativeAppPathModifier + '**/*.vue'); 773 | 774 | // add unit test directories into include array 775 | if (fs.existsSync(path.join(dirPathPrefix, 'tests'))) { 776 | if (!tsConfigContent.include.includes('tests/**/*.ts')) tsConfigContent.include.push('tests/**/*.ts'); 777 | if (!tsConfigContent.include.includes('tests/**/*.tsx')) tsConfigContent.include.push('tests/**/*.tsx'); 778 | } 779 | 780 | if (options.isNativeOnly) { 781 | // edit some of the options in compilerOptions.paths object array 782 | tsConfigContent.compilerOptions.paths['src/*'] = [nativeAppPathModifier + '*']; 783 | 784 | // remove some items from the include array 785 | tsConfigContent.include = await removeFromArray(tsConfigContent.include, 'src/**/*.ts'); 786 | tsConfigContent.include = await removeFromArray(tsConfigContent.include, 'src/**/*.tsx'); 787 | tsConfigContent.include = await removeFromArray(tsConfigContent.include, 'src/**/*.vue'); 788 | 789 | fs.writeJsonSync(tsConfigPath, tsConfigContent, { 790 | spaces: 2, 791 | encoding: 'utf8' 792 | }); 793 | } else { 794 | tsConfigContent.compilerOptions.paths['src/*'] = [nativeAppPathModifier + '*']; 795 | 796 | fs.writeJsonSync(tsConfigPath, tsConfigContent, { 797 | spaces: 2, 798 | encoding: 'utf8' 799 | }); 800 | } 801 | } catch (err) { 802 | throw err; 803 | } 804 | }); 805 | 806 | // Use the generator's render function to render individual files passed in from an array. 807 | // Will iterate through the array and then construct and object that is passed to render() 808 | const renderFilesIndividually = (module.exports.renderFilesIndividually = async ( 809 | api, 810 | options, 811 | jsOrTs, 812 | files, 813 | commonRenderOptions, 814 | srcPathPrefix, 815 | destPathPrefix 816 | ) => { 817 | try { 818 | const obj = {}; 819 | 820 | for (let file of files) { 821 | let newFile = file; 822 | 823 | // renames .js files to .ts 824 | if (file.slice(-3) === '.js' || file.slice(-3) === '.ts') newFile = file.substring(0, file.length - 3) + jsOrTs; 825 | 826 | if ((!api.hasPlugin('typescript') && file !== 'tsconfig.json') || api.hasPlugin('typescript')) 827 | obj[path.join(destPathPrefix, newFile)] = path.join(srcPathPrefix, file); 828 | } 829 | 830 | api.render(obj, commonRenderOptions); 831 | } catch (err) { 832 | throw err; 833 | } 834 | }); 835 | 836 | // Good chunk of the following code comes from vue-cli/packages/@vue/cli/lib/GeneratorAPI.js 837 | // Specifically the render function. We want to render the entire directory, but passing just 838 | // the directory to render doesn't give us the ability to tell where to put it as the cli's render 839 | // function lacks a simple directory in and directory out option. So, we have to get the contents 840 | // of the passed in directory and then render each file individually to where we want it via 841 | // the render function's isObject(source) option that we use in our renderFilesIndividually function. 842 | 843 | // eslint-disable-next-line prettier/prettier 844 | // eslint-disable-next-line max-len 845 | const renderDirectoryStructure = (module.exports.renderDirectoryStructure = async ( 846 | api, 847 | options, 848 | rootOptions, 849 | jsOrTs, 850 | commonRenderOptions, 851 | srcPathPrefix, 852 | destPathPrefix 853 | ) => { 854 | try { 855 | const files = new Array(); 856 | const _files = await getAllFilesInDirStructure(srcPathPrefix, __dirname); 857 | 858 | for (const rawPath of _files) { 859 | // // // let filename = path.basename(rawPath); 860 | // // // // dotfiles are ignored when published to npm, therefore in templates 861 | // // // // we need to use underscore instead (e.g. "_gitignore") 862 | // // // if (filename.charAt(0) === '_' && filename.charAt(1) !== '_') { 863 | // // // filename = `.${filename.slice(1)}`; 864 | // // // } 865 | // // // if (filename.charAt(0) === '_' && filename.charAt(1) === '_') { 866 | // // // filename = `${filename.slice(1)}`; 867 | // // // } 868 | 869 | // only import styles based on the type of preprocessor you do or do not have. 870 | // Essentially acts as filter as you iterate through the list of files in a directory structure 871 | if ( 872 | rawPath.slice(-4) == '.css' || 873 | rawPath.slice(-5) == '.scss' || 874 | rawPath.slice(-5) == '.sass' || 875 | rawPath.slice(-5) == '.less' || 876 | rawPath.slice(-5) == '.styl' || 877 | rawPath.slice(-7) == '.stylus' 878 | ) { 879 | if (rootOptions.cssPreprocessor) { 880 | switch (rootOptions.cssPreprocessor) { 881 | case 'scss': 882 | if (rawPath.slice(-5) == '.scss' || rawPath.slice(-5) == '.sass') files.push(rawPath); 883 | break; 884 | case 'sass': 885 | if (rawPath.slice(-5) == '.scss' || rawPath.slice(-5) == '.sass') files.push(rawPath); 886 | break; 887 | case 'dart-sass': 888 | if (rawPath.slice(-5) == '.scss' || rawPath.slice(-5) == '.sass') files.push(rawPath); 889 | break; 890 | case 'less': 891 | if (rawPath.slice(-5) == '.less') files.push(rawPath); 892 | break; 893 | case 'stylus': 894 | if (rawPath.slice(-5) == '.styl' || rawPath.slice(-7) == '.stylus') files.push(rawPath); 895 | break; 896 | } 897 | } else { 898 | if (rawPath.slice(-4) == '.css') files.push(rawPath); 899 | } 900 | } else { 901 | files.push(rawPath); 902 | } 903 | } 904 | renderFilesIndividually(api, options, jsOrTs, files, commonRenderOptions, srcPathPrefix, destPathPrefix); 905 | } catch (err) { 906 | throw err; 907 | } 908 | }); 909 | 910 | // THIS FUNCTION MAY NOT LONGER BE NEEDED AS OF 0.0.16 911 | // WILL KEEP THIS COMMENTED OUT CODE IN FOR A FEW OF RELEASES 912 | // // extract callsite file location using error stack 913 | // const extractCallDir = (module.exports.extractCallDir = () => { 914 | // try { 915 | // const obj = {}; 916 | // console.log('__dirname - ', __dirname); 917 | // Error.captureStackTrace(obj); 918 | // const callSite = obj.stack.split('\n')[3]; 919 | // console.log('callSite - ', callSite); 920 | 921 | // let { fileName } = /(?[^(]+):[0-9]+:[0-9]+/.exec(callSite).groups; 922 | // console.log('fileName 1 - ', fileName); 923 | 924 | // if (fileName.indexOf('file') >= 0) { 925 | // fileName = new URL(fileName).pathname; 926 | // } 927 | 928 | // if (fileName.indexOf(fileName.length - 1) === ')') { 929 | // fileName = fileName.splice(0, fileName.length - 1); 930 | // } 931 | 932 | // console.log(`fileName 2 - '`, fileName + `'`); 933 | 934 | // fileName = fileName.replace('at ', ''); 935 | // console.log(`fileName 3 - '`, fileName) + `'`; 936 | 937 | // let dirname = path.dirname(fileName); 938 | // console.log(`dirname - '`, dirname + `'`); 939 | 940 | // return __dirname; 941 | // } catch (err) { 942 | // throw err; 943 | // } 944 | // }); 945 | 946 | // utility function used to get all the files in a directory structure. is recursive in nature due to globby 947 | const getAllFilesInDirStructure = (module.exports.replaceInFile = async (srcPathPrefix, baseDir) => { 948 | try { 949 | const source = path.resolve(baseDir, srcPathPrefix); 950 | const globby = require('globby'); 951 | const _files = await globby(['**/*'], { 952 | cwd: source 953 | }); 954 | 955 | return _files; 956 | } catch (error) { 957 | console.log(error); 958 | } 959 | }); 960 | 961 | // utility function used to remove sections of strings from files 962 | const replaceInFile = (module.exports.replaceInFile = async (options) => { 963 | try { 964 | await replace(options); 965 | } catch (error) { 966 | console.error('Error occurred:', error); 967 | } 968 | }); 969 | 970 | // utility function used to remove items from an array that match 'item' 971 | const removeFromArray = (module.exports.removeFromArray = async (array, item) => { 972 | const index = array.indexOf(item); 973 | if (index !== -1) array.splice(index, 1); 974 | return array; 975 | }); 976 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/app.gradle: -------------------------------------------------------------------------------- 1 | // Add your native dependencies here: 2 | 3 | android { 4 | defaultConfig { 5 | generatedDensities = [] 6 | applicationId = "__PACKAGE__" 7 | } 8 | aaptOptions { 9 | additionalParameters "--no-version-vectors" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-hdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-hdpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-hdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-hdpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-hdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-hdpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-ldpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-ldpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-ldpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-ldpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-ldpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-ldpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-mdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-mdpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-mdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-mdpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-mdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-mdpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-nodpi/splash_screen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xhdpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xhdpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xhdpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxhdpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxhdpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxhdpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxxhdpi/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxxhdpi/background.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxxhdpi/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxxhdpi/icon.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/drawable-xxxhdpi/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/Android/drawable-xxxhdpi/logo.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values-v21/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3d5afe 4 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values-v21/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%- applicationName %> 4 | <%- applicationName %> 5 | 6 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 14 | 15 | 16 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #F5F5F5 4 | #757575 5 | #33B5E5 6 | #272734 7 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%- applicationName %> 4 | <%- applicationName %> 5 | 6 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/Android/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 20 | 21 | 22 | 29 | 30 | 32 | 33 | 34 | 39 | 40 | 42 | 43 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "icon-29.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "icon-29@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon-29@3x.png", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "icon-40@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon-40@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "icon-60@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon-60@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "29x29", 47 | "idiom" : "ipad", 48 | "filename" : "icon-29.png", 49 | "scale" : "1x" 50 | }, 51 | { 52 | "size" : "29x29", 53 | "idiom" : "ipad", 54 | "filename" : "icon-29@2x.png", 55 | "scale" : "2x" 56 | }, 57 | { 58 | "size" : "40x40", 59 | "idiom" : "ipad", 60 | "filename" : "icon-40.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "40x40", 65 | "idiom" : "ipad", 66 | "filename" : "icon-40@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "76x76", 71 | "idiom" : "ipad", 72 | "filename" : "icon-76.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "76x76", 77 | "idiom" : "ipad", 78 | "filename" : "icon-76@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "83.5x83.5", 83 | "idiom" : "ipad", 84 | "filename" : "icon-83.5@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "1024x1024", 89 | "idiom" : "ios-marketing", 90 | "filename" : "icon-1024.png", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-1024.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "2436h", 7 | "filename" : "Default-1125h.png", 8 | "minimum-system-version" : "11.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "orientation" : "landscape", 14 | "idiom" : "iphone", 15 | "extent" : "full-screen", 16 | "filename" : "Default-Landscape-X.png", 17 | "minimum-system-version" : "11.0", 18 | "subtype" : "2436h", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "extent" : "full-screen", 23 | "idiom" : "iphone", 24 | "subtype" : "736h", 25 | "filename" : "Default-736h@3x.png", 26 | "minimum-system-version" : "8.0", 27 | "orientation" : "portrait", 28 | "scale" : "3x" 29 | }, 30 | { 31 | "extent" : "full-screen", 32 | "idiom" : "iphone", 33 | "subtype" : "736h", 34 | "filename" : "Default-Landscape@3x.png", 35 | "minimum-system-version" : "8.0", 36 | "orientation" : "landscape", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "extent" : "full-screen", 41 | "idiom" : "iphone", 42 | "subtype" : "667h", 43 | "filename" : "Default-667h@2x.png", 44 | "minimum-system-version" : "8.0", 45 | "orientation" : "portrait", 46 | "scale" : "2x" 47 | }, 48 | { 49 | "orientation" : "portrait", 50 | "idiom" : "iphone", 51 | "filename" : "Default@2x.png", 52 | "extent" : "full-screen", 53 | "minimum-system-version" : "7.0", 54 | "scale" : "2x" 55 | }, 56 | { 57 | "extent" : "full-screen", 58 | "idiom" : "iphone", 59 | "subtype" : "retina4", 60 | "filename" : "Default-568h@2x.png", 61 | "minimum-system-version" : "7.0", 62 | "orientation" : "portrait", 63 | "scale" : "2x" 64 | }, 65 | { 66 | "orientation" : "portrait", 67 | "idiom" : "ipad", 68 | "filename" : "Default-Portrait.png", 69 | "extent" : "full-screen", 70 | "minimum-system-version" : "7.0", 71 | "scale" : "1x" 72 | }, 73 | { 74 | "orientation" : "landscape", 75 | "idiom" : "ipad", 76 | "filename" : "Default-Landscape.png", 77 | "extent" : "full-screen", 78 | "minimum-system-version" : "7.0", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "orientation" : "portrait", 83 | "idiom" : "ipad", 84 | "filename" : "Default-Portrait@2x.png", 85 | "extent" : "full-screen", 86 | "minimum-system-version" : "7.0", 87 | "scale" : "2x" 88 | }, 89 | { 90 | "orientation" : "landscape", 91 | "idiom" : "ipad", 92 | "filename" : "Default-Landscape@2x.png", 93 | "extent" : "full-screen", 94 | "minimum-system-version" : "7.0", 95 | "scale" : "2x" 96 | }, 97 | { 98 | "orientation" : "portrait", 99 | "idiom" : "iphone", 100 | "filename" : "Default.png", 101 | "extent" : "full-screen", 102 | "scale" : "1x" 103 | }, 104 | { 105 | "orientation" : "portrait", 106 | "idiom" : "iphone", 107 | "filename" : "Default@2x.png", 108 | "extent" : "full-screen", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "orientation" : "portrait", 113 | "idiom" : "iphone", 114 | "filename" : "Default-568h@2x.png", 115 | "extent" : "full-screen", 116 | "subtype" : "retina4", 117 | "scale" : "2x" 118 | }, 119 | { 120 | "orientation" : "portrait", 121 | "idiom" : "ipad", 122 | "extent" : "to-status-bar", 123 | "scale" : "1x" 124 | }, 125 | { 126 | "orientation" : "portrait", 127 | "idiom" : "ipad", 128 | "filename" : "Default-Portrait.png", 129 | "extent" : "full-screen", 130 | "scale" : "1x" 131 | }, 132 | { 133 | "orientation" : "landscape", 134 | "idiom" : "ipad", 135 | "extent" : "to-status-bar", 136 | "scale" : "1x" 137 | }, 138 | { 139 | "orientation" : "landscape", 140 | "idiom" : "ipad", 141 | "filename" : "Default-Landscape.png", 142 | "extent" : "full-screen", 143 | "scale" : "1x" 144 | }, 145 | { 146 | "orientation" : "portrait", 147 | "idiom" : "ipad", 148 | "extent" : "to-status-bar", 149 | "scale" : "2x" 150 | }, 151 | { 152 | "orientation" : "portrait", 153 | "idiom" : "ipad", 154 | "filename" : "Default-Portrait@2x.png", 155 | "extent" : "full-screen", 156 | "scale" : "2x" 157 | }, 158 | { 159 | "orientation" : "landscape", 160 | "idiom" : "ipad", 161 | "extent" : "to-status-bar", 162 | "scale" : "2x" 163 | }, 164 | { 165 | "orientation" : "landscape", 166 | "idiom" : "ipad", 167 | "filename" : "Default-Landscape@2x.png", 168 | "extent" : "full-screen", 169 | "scale" : "2x" 170 | } 171 | ], 172 | "info" : { 173 | "version" : 1, 174 | "author" : "xcode" 175 | } 176 | } -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-1125h.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-1125h.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-568h@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-667h@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-736h@3x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape-X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape-X.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Landscape@3x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default-Portrait@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchImage.launchimage/Default@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchScreen-AspectFill.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchScreen-AspectFill@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.AspectFill.imageset/LaunchScreen-AspectFill@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchScreen-Center.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchScreen-Center@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/App_Resources/iOS/Assets.xcassets/LaunchScreen.Center.imageset/LaunchScreen-Center@2x.png -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | <%- applicationName %> 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | <%- applicationVersion %> 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | <%- applicationVersion %> 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiresFullScreen 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /generator/templates/App_Resources/iOS/build.xcconfig: -------------------------------------------------------------------------------- 1 | // You can add custom settings here 2 | // for example you can uncomment the following line to force distribution code signing 3 | // CODE_SIGN_IDENTITY = iPhone Distribution 4 | // To build for device with Xcode 8 you need to specify your development team. More info: https://developer.apple.com/library/prerelease/content/releasenotes/DeveloperTools/RN-Xcode/Introduction.html 5 | // DEVELOPMENT_TEAM = YOUR_TEAM_ID; 6 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 7 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 8 | -------------------------------------------------------------------------------- /generator/templates/nvw/src/App.vue: -------------------------------------------------------------------------------- 1 | <%_ if (rootOptions.router) { _%> 2 | <%# -------------------- IS Using vue-router -------------------- -%> 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | <%_ } else { _%> 23 | <%# -------------------- IS NOT Using vue-router -------------------- -%> 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | <%_ } _%> 45 | <%_ if (!usingTS && rootOptions.router) { _%> 46 | <%# -------------------- IS NOT Using TypeScript AND IS Using vue-router -------------------- -%> 47 | 70 | <%_ } else if (!usingTS && !rootOptions.router) { _%> 71 | <%# -------------------- IS NOT Using TypeScript AND IS NOT Using vue-router -------------------- -%> 72 | 89 | <%_ } else if (usingTS && rootOptions.router) { _%> 90 | <%# -------------------- IS Using TypeScript AND IS Using vue-router -------------------- -%> 91 | 112 | <%_ } else if (usingTS && !rootOptions.router) { _%> 113 | <%# -------------------- IS Using TypeScript AND IS NOT Using vue-router -------------------- -%> 114 | 131 | <%_ } else { _%> 132 | <%# -------------------- don't do anything -------------------- -%> 133 | <%_ } _%> 134 | 135 | <%_ if (rootOptions.cssPreprocessor) { _%> 136 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 137 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 138 | 151 | 154 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 155 | <%# -------------------- IS Using stylus -------------------- -%> 156 | 167 | 170 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 171 | <%# -------------------- IS Using Less -------------------- -%> 172 | 185 | 188 | <%_ } _%> 189 | <%_ } else { _%> 190 | <%# -------------------- IS Using standard CSS -------------------- -%> 191 | 203 | 206 | <%_ } _%> 207 | -------------------------------------------------------------------------------- /generator/templates/nvw/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/nvw/src/assets/logo.png -------------------------------------------------------------------------------- /generator/templates/nvw/src/components/HelloWorld.android.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/nvw/src/components/HelloWorld.ios.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/nvw/src/components/HelloWorld.native.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/nvw/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 19 | <%_ } else { _%> 20 | <%# -------------------- Is Using TypeScript -------------------- -%> 21 | 32 | <%_ } _%> 33 | 34 | <%_ if (rootOptions.cssPreprocessor) { _%> 35 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 36 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 37 | 52 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 53 | <%# -------------------- IS Using stylus -------------------- -%> 54 | 68 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 69 | <%# -------------------- IS Using Less -------------------- -%> 70 | 85 | <%_ } _%> 86 | <%_ } else { _%> 87 | <%# -------------------- IS Using standard CSS -------------------- -%> 88 | 103 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/nvw/src/components/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/nvw/src/components/icon.png -------------------------------------------------------------------------------- /generator/templates/nvw/src/main.js: -------------------------------------------------------------------------------- 1 | --- 2 | extend: '@vue/cli-service/generator/template/src/main.js' 3 | replace: 4 | - !!js/regexp /import Vue from 'vue'/ 5 | - !!js/regexp /import App from './App.vue'/ 6 | - !!js/regexp /Vue.config.productionTip = false/ 7 | - !!js/regexp /h => h\(App\),/ 8 | - !!js/regexp /}\)\.\$mount\('#app'\)/ 9 | --- 10 | 11 | <%# REPLACE %> 12 | import Vue from 'vue'; 13 | <%# END_REPLACE %> 14 | 15 | <%# REPLACE %> 16 | import App from '~/App.vue'; 17 | import { Page, ActionBar, GridLayout, Button, Img, Label } from 'nativescript-vue-web'; 18 | 19 | Vue.component('Page', Page); 20 | Vue.component('ActionBar', ActionBar); 21 | Vue.component('GridLayout', GridLayout); 22 | Vue.component('Button', Button); 23 | Vue.component('Img', Img); 24 | Vue.component('Label', Label); 25 | 26 | <%# END_REPLACE %> 27 | 28 | <%# REPLACE %> 29 | Vue.config.productionTip = false; 30 | <%# END_REPLACE %> 31 | 32 | <%# REPLACE %> 33 | (h) => h(App), 34 | <%# END_REPLACE %> 35 | 36 | <%# REPLACE %> 37 | }).$mount('#app'); 38 | <%# END_REPLACE %> -------------------------------------------------------------------------------- /generator/templates/nvw/src/main.native.js: -------------------------------------------------------------------------------- 1 | --- 2 | extend: '@vue/cli-service/generator/template/src/main.js' 3 | replace: 4 | - !!js/regexp /import Vue from 'vue'/ 5 | - !!js/regexp /Vue.config.productionTip = false/ 6 | - !!js/regexp /h => h\(App\),/ 7 | - !!js/regexp /}\)\.\$mount\('#app'\)/ 8 | --- 9 | 10 | <%# REPLACE %> 11 | import Vue from 'nativescript-vue'; 12 | <%# END_REPLACE %> 13 | 14 | <%# REPLACE %> 15 | // Set the following to `true` to hide the logs created by nativescript-vue 16 | Vue.config.silent = false; 17 | // Set the following to `false` to not colorize the logs created by nativescript-vue 18 | // disabled in template due to typing issue for Typescript projects....NEEDS TO BE FIXED 19 | // Vue.config.debug = true; 20 | <%# END_REPLACE %> 21 | 22 | <%# REPLACE %> 23 | (h) => h('frame', [h(App)]), 24 | <%# END_REPLACE %> 25 | 26 | <%# REPLACE %> 27 | }).$start(); 28 | <%# END_REPLACE %> -------------------------------------------------------------------------------- /generator/templates/nvw/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "android": { 3 | "v8Flags": "--expose_gc", 4 | "markingMode": "none" 5 | }, 6 | "main": "main.native", 7 | "name": "<%- applicationName %>", 8 | "version": "<%- applicationVersion %>" 9 | } 10 | -------------------------------------------------------------------------------- /generator/templates/nvw/src/router.js: -------------------------------------------------------------------------------- 1 | --- 2 | extend: '@vue/cli-service/generator/router.js' 3 | replace: 4 | - !!js/regexp /import Vue from 'vue'/ 5 | - !!js/regexp /import Router from 'vue-router'/ 6 | - !!js/regexp /Vue.use\(Router\)/ 7 | - !!js/regexp /import Home from './views/Home.vue'/ 8 | - !!js/regexp /'./views/About.vue'\)/ 9 | - !!js/regexp /\}\)/ 10 | --- 11 | 12 | <%# REPLACE %> 13 | import Vue from 'vue'; 14 | <%# END_REPLACE %> 15 | 16 | <%# REPLACE %> 17 | import Router from 'vue-router'; 18 | <%# END_REPLACE %> 19 | 20 | <%# REPLACE %> 21 | Vue.use(Router); 22 | <%# END_REPLACE %> 23 | 24 | <%# REPLACE %> 25 | import Home from '~/views/Home.vue'; 26 | <%# END_REPLACE %> 27 | 28 | <%# REPLACE %> 29 | '~/views/About.vue'), 30 | <%# END_REPLACE %> 31 | 32 | <%# REPLACE %> 33 | }); 34 | <%# END_REPLACE %> 35 | -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-one.css: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | } 24 | 25 | .w-navbar .w-title { 26 | margin-left: auto; 27 | margin-right: auto; 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | } 41 | 42 | .w-container .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-one.less: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | } 24 | 25 | .w-navbar .w-title { 26 | margin-left: auto; 27 | margin-right: auto; 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | } 41 | 42 | .w-container .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-one.scss: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | 24 | .w-title { 25 | margin-left: auto; 26 | margin-right: auto; 27 | } 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | 41 | 42 | .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-one.styl: -------------------------------------------------------------------------------- 1 | ActionBar 2 | color #42b983 3 | 4 | .w-navbar 5 | color #42b983 6 | position fixed 7 | z-index 10000 8 | height 3em 9 | width 100% 10 | top 0px 11 | left 0px 12 | margin auto 13 | list-style none 14 | display flex 15 | align-items center 16 | padding 0 10px 17 | -webkit-box-shadow -8px 8px 6px -7px #999 18 | -moz-box-shadow -8px 8px 6px -7px #999 19 | box-shadow -8px 8px 6px -7px #999 20 | 21 | .w-title 22 | margin-left auto 23 | margin-right auto 24 | 25 | .w-container 26 | height 100% 27 | width 100% 28 | padding-top 3em 29 | position relative 30 | overflow hidden 31 | display flex 32 | flex-direction column 33 | justify-content top 34 | align-items center 35 | 36 | .w-button 37 | width 50% 38 | height 2em 39 | margin 0.25em 40 | display flex 41 | justify-content center 42 | align-items center 43 | background-color #d7d7d7 44 | border-width 0px 45 | font-weight 600 46 | border-radius 3px -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-two.css: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-two.less: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-two.scss: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/nvw/src/styles/style-two.styl: -------------------------------------------------------------------------------- 1 | ActionBar 2 | color #000000 3 | 4 | .w-navbar 5 | color #000000 -------------------------------------------------------------------------------- /generator/templates/nvw/src/views/About.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <%_ if (!usingTS) { _%> 17 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 18 | 28 | <%_ } else { _%> 29 | <%# -------------------- Is Using TypeScript -------------------- -%> 30 | 41 | <%_ } _%> 42 | 43 | <%_ if (rootOptions.cssPreprocessor) { _%> 44 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 45 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 46 | 62 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 63 | <%# -------------------- IS Using stylus -------------------- -%> 64 | 80 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 81 | <%# -------------------- IS Using Less -------------------- -%> 82 | 98 | <%_ } _%> 99 | <%_ } else { _%> 100 | <%# -------------------- IS Using standard CSS -------------------- -%> 101 | 117 | <%_ } _%> 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /generator/templates/nvw/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%_ if (!usingTS) { _%> 21 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 22 | 41 | <%_ } else { _%> 42 | <%# -------------------- Is Using TypeScript -------------------- -%> 43 | 61 | <%_ } _%> 62 | 63 | <%_ if (rootOptions.cssPreprocessor) { _%> 64 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 65 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 66 | 81 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 82 | <%# -------------------- IS Using stylus -------------------- -%> 83 | 98 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 99 | <%# -------------------- IS Using Less -------------------- -%> 100 | 115 | <%_ } _%> 116 | <%_ } else { _%> 117 | <%# -------------------- IS Using standard CSS -------------------- -%> 118 | 133 | <%_ } _%> 134 | -------------------------------------------------------------------------------- /generator/templates/simple/src/App.vue: -------------------------------------------------------------------------------- 1 | <%_ if (rootOptions.router) { _%> 2 | <%# -------------------- IS Using vue-router -------------------- -%> 3 | <%_ if (!options.isNativeOnly) { _%> 4 | 5 | 6 | 7 | 8 | {{navbarTitle}} 9 | 10 | 11 | 12 | Home 13 | 14 | About 15 | 16 | 17 | 18 | 19 | 20 | <%_ } else { _%> 21 | 22 | <%_ } _%> 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | <%_ } else { _%> 32 | <%# -------------------- IS NOT Using vue-router -------------------- -%> 33 | <%_ if (!options.isNativeOnly) { _%> 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | <%_ } else { _%> 44 | 45 | <%_ } _%> 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | <%_ } _%> 54 | <%_ if (!usingTS) { _%> 55 | <%# -------------------- IS NOT Using TypeScript -------------------- -%> 56 | 96 | <%_ } else { _%> 97 | <%# -------------------- IS Using TypeScript -------------------- -%> 98 | 141 | <%_ } _%> 142 | 143 | 144 | <%_ if (rootOptions.cssPreprocessor) { _%> 145 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 146 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 147 | 156 | 165 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 166 | <%# -------------------- IS Using stylus -------------------- -%> 167 | 175 | 178 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 179 | <%# -------------------- IS Using Less -------------------- -%> 180 | 189 | 192 | <%_ } _%> 193 | <%_ } else { _%> 194 | <%# -------------------- IS Using standard CSS -------------------- -%> 195 | 203 | 206 | <%_ } _%> 207 | -------------------------------------------------------------------------------- /generator/templates/simple/src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/simple/src/assets/logo.png -------------------------------------------------------------------------------- /generator/templates/simple/src/components/HelloWorld.android.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/simple/src/components/HelloWorld.ios.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/simple/src/components/HelloWorld.native.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%_ if (!usingTS) { _%> 9 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 10 | 18 | <%_ } else { _%> 19 | <%# -------------------- Is Using TypeScript -------------------- -%> 20 | 31 | <%_ } _%> 32 | 33 | <%_ if (rootOptions.cssPreprocessor) { _%> 34 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 35 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 36 | 47 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 48 | <%# -------------------- IS Using stylus -------------------- -%> 49 | 58 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 59 | <%# -------------------- IS Using Less -------------------- -%> 60 | 71 | <%_ } _%> 72 | <%_ } else { _%> 73 | <%# -------------------- IS Using standard CSS -------------------- -%> 74 | 85 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/simple/src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{msg}} 4 | 5 | 6 | 7 | <%_ if (!usingTS) { _%> 8 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 9 | 17 | <%_ } else { _%> 18 | <%# -------------------- Is Using TypeScript -------------------- -%> 19 | 29 | <%_ } _%> 30 | 31 | <%_ if (rootOptions.cssPreprocessor) { _%> 32 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 33 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 34 | 49 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 50 | <%# -------------------- IS Using stylus -------------------- -%> 51 | 65 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 66 | <%# -------------------- IS Using Less -------------------- -%> 67 | 82 | <%_ } _%> 83 | <%_ } else { _%> 84 | <%# -------------------- IS Using standard CSS -------------------- -%> 85 | 100 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/simple/src/components/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nativescript-vue/vue-cli-plugin-nativescript-vue/5b04c4c7cb2197303839237482803eaf81067179/generator/templates/simple/src/components/icon.png -------------------------------------------------------------------------------- /generator/templates/simple/src/main.js: -------------------------------------------------------------------------------- 1 | --- 2 | extend: '@vue/cli-service/generator/template/src/main.js' 3 | replace: 4 | - !!js/regexp /import Vue from 'vue'/ 5 | - !!js/regexp /import App from './App.vue'/ 6 | - !!js/regexp /Vue.config.productionTip = false/ 7 | - !!js/regexp /h => h\(App\),/ 8 | - !!js/regexp /}\)\.\$mount\('#app'\)/ 9 | --- 10 | 11 | <%# REPLACE %> 12 | import Vue from 'vue'; 13 | <%# END_REPLACE %> 14 | 15 | <%# REPLACE %> 16 | import App from '~/App.vue'; 17 | <%# END_REPLACE %> 18 | 19 | <%# REPLACE %> 20 | Vue.config.productionTip = false; 21 | <%# END_REPLACE %> 22 | 23 | <%# REPLACE %> 24 | (h) => h(App), 25 | <%# END_REPLACE %> 26 | 27 | <%# REPLACE %> 28 | }).$mount('#app'); 29 | <%# END_REPLACE %> -------------------------------------------------------------------------------- /generator/templates/simple/src/main.native.js: -------------------------------------------------------------------------------- 1 | import Vue from 'nativescript-vue'; 2 | <%_ if (rootOptions.router) { _%> 3 | import Navigator from 'nativescript-vue-navigator' 4 | <%_ } _%> 5 | 6 | import App from './App.vue'; 7 | <%_ if (rootOptions.router) { _%> 8 | import { options } from './router'; 9 | 10 | // adapt vue-router routes to nativescript-vue-navigator 11 | const routes = options.routes.reduce((data, route) => { 12 | data[route.name] = { 13 | component: route.component 14 | } 15 | return data 16 | }, {}); 17 | 18 | Vue.use(Navigator, { routes }); 19 | <%_ } _%> 20 | 21 | // Set the following to `true` to hide the logs created by nativescript-vue 22 | Vue.config.silent = false; 23 | // Set the following to `false` to not colorize the logs created by nativescript-vue 24 | // disabled in template due to typing issue for Typescript projects....NEEDS TO BE FIXED 25 | // Vue.config.debug = true; 26 | 27 | new Vue({ 28 | render: h => h('frame', [h(App)]), 29 | }).$start(); 30 | -------------------------------------------------------------------------------- /generator/templates/simple/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "android": { 3 | "v8Flags": "--expose_gc", 4 | "markingMode": "none" 5 | }, 6 | "main": "main.native", 7 | "name": "<%- applicationName %>", 8 | "version": "<%- applicationVersion %>" 9 | } 10 | -------------------------------------------------------------------------------- /generator/templates/simple/src/router.js: -------------------------------------------------------------------------------- 1 | --- 2 | extend: '@vue/cli-service/generator/router.js' 3 | replace: 4 | - !!js/regexp /import Vue from 'vue'/ 5 | - !!js/regexp /import Router from 'vue-router'/ 6 | - !!js/regexp /Vue.use\(Router\)/ 7 | - !!js/regexp /export default new Router\(\{/ 8 | - !!js/regexp /import Home from '\./views/Home.vue'/ 9 | - !!js/regexp /\(\) => import(.*)\.\/views\/About\.vue'\)/ 10 | - !!js/regexp /(\s+)\/\/ (.*)/ 11 | - !!js/regexp /(\s+)\/\/ (.*)/ 12 | - !!js/regexp /(\s+)\/\/ (.*)/ 13 | - !!js/regexp /\}\)/ 14 | --- 15 | 16 | <%# REPLACE %> 17 | import Vue from 'vue'; 18 | <%# END_REPLACE %> 19 | 20 | <%# REPLACE %> 21 | import Router from 'vue-router'; 22 | <%# END_REPLACE %> 23 | 24 | <%# REPLACE %> 25 | Vue.use(Router); 26 | <%# END_REPLACE %> 27 | 28 | <%# REPLACE %> 29 | export const options = { 30 | <%# END_REPLACE %> 31 | 32 | <%# REPLACE %> 33 | import Home from '~/views/Home.vue'; 34 | import About from '~/views/About.vue'; 35 | <%# END_REPLACE %> 36 | 37 | <%# REPLACE %> 38 | About, 39 | <%# END_REPLACE %> 40 | 41 | <%# REPLACE %> 42 | <%# END_REPLACE %> 43 | 44 | <%# REPLACE %> 45 | <%# END_REPLACE %> 46 | 47 | <%# REPLACE %> 48 | <%# END_REPLACE %> 49 | 50 | <%# REPLACE %> 51 | }; 52 | export default new Router(options); 53 | <%# END_REPLACE %> 54 | -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-one.css: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | } 24 | 25 | .w-navbar .w-title { 26 | margin-left: auto; 27 | margin-right: auto; 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | } 41 | 42 | .w-container .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-one.less: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | } 24 | 25 | .w-navbar .w-title { 26 | margin-left: auto; 27 | margin-right: auto; 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | } 41 | 42 | .w-container .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-one.scss: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #42b983; 3 | } 4 | 5 | .w-navbar { 6 | color: #42b983; 7 | position: fixed; 8 | z-index: 10000; 9 | height: 3em; 10 | width: 100%; 11 | top: 0px; 12 | left: 0px; 13 | margin: auto; 14 | list-style: none; 15 | 16 | display: flex; 17 | align-items: center; 18 | padding: 0 10px; 19 | 20 | -webkit-box-shadow: -8px 8px 6px -7px #999; 21 | -moz-box-shadow: -8px 8px 6px -7px #999; 22 | box-shadow: -8px 8px 6px -7px #999; 23 | 24 | .w-title { 25 | margin-left: auto; 26 | margin-right: auto; 27 | } 28 | } 29 | 30 | .w-container { 31 | height: 100%; 32 | width: 100%; 33 | padding-top: 3em; 34 | position: relative; 35 | overflow: hidden; 36 | display: flex; 37 | flex-direction: column; 38 | justify-content: top; 39 | align-items: center; 40 | 41 | 42 | .w-button { 43 | width: 50%; 44 | height: 2em; 45 | margin: .25em; 46 | display: flex; 47 | justify-content: center; 48 | align-items: center; 49 | background-color: #d7d7d7; 50 | border-width: 0px; 51 | font-weight: 600; 52 | border-radius: 3px; 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-one.styl: -------------------------------------------------------------------------------- 1 | ActionBar 2 | color #42b983 3 | 4 | .w-navbar 5 | color #42b983 6 | position fixed 7 | z-index 10000 8 | height 3em 9 | width 100% 10 | top 0px 11 | left 0px 12 | margin auto 13 | list-style none 14 | display flex 15 | align-items center 16 | padding 0 10px 17 | -webkit-box-shadow -8px 8px 6px -7px #999 18 | -moz-box-shadow -8px 8px 6px -7px #999 19 | box-shadow -8px 8px 6px -7px #999 20 | 21 | .w-title 22 | margin-left auto 23 | margin-right auto 24 | 25 | .w-container 26 | height 100% 27 | width 100% 28 | padding-top 3em 29 | position relative 30 | overflow hidden 31 | display flex 32 | flex-direction column 33 | justify-content top 34 | align-items center 35 | 36 | .w-button 37 | width 50% 38 | height 2em 39 | margin 0.25em 40 | display flex 41 | justify-content center 42 | align-items center 43 | background-color #d7d7d7 44 | border-width 0px 45 | font-weight 600 46 | border-radius 3px -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-two.css: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-two.less: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-two.scss: -------------------------------------------------------------------------------- 1 | ActionBar { 2 | color: #000000; 3 | } 4 | 5 | .w-navbar { 6 | color: #000000; 7 | } -------------------------------------------------------------------------------- /generator/templates/simple/src/styles/style-two.styl: -------------------------------------------------------------------------------- 1 | ActionBar 2 | color #000000 3 | 4 | .w-navbar 5 | color #000000 -------------------------------------------------------------------------------- /generator/templates/simple/src/views/About.vue: -------------------------------------------------------------------------------- 1 | <%_ if (!options.isNativeOnly) { _%> 2 | 3 | 4 | 5 | This is an about page 6 | 7 | 8 | 9 | 10 | <%_ } else { _%> 11 | 12 | <%_ } _%> 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | <%_ if (!usingTS) { _%> 21 | 31 | <%_ } else { _%> 32 | 43 | <%_ } _%> 44 | <%_ if (!usingTS) { _%> 45 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 46 | <%# -------------------- Remove this line and Uncomment the next to use script tag - Prettier formatting bug removes all script tags if these are left in -------------------- -%> 47 | <%# -------------------- -------------------- -%> 48 | <%_ } else { _%> 49 | <%# -------------------- Is Using TypeScript -------------------- -%> 50 | <%# -------------------- Remove this line and Uncomment the next to use script tag - Prettier formatting bug removes all script tags if these are left in -------------------- -%> 51 | <%# -------------------- -------------------- -%> 52 | <%_ } _%> 53 | 54 | <%_ if (rootOptions.cssPreprocessor) { _%> 55 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 56 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 57 | 61 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 62 | <%# -------------------- IS Using stylus -------------------- -%> 63 | 67 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 68 | <%# -------------------- IS Using Less -------------------- -%> 69 | 73 | <%_ } _%> 74 | <%_ } else { _%> 75 | <%# -------------------- IS Using standard CSS -------------------- -%> 76 | 80 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/simple/src/views/Home.vue: -------------------------------------------------------------------------------- 1 | <%_ if (!options.isNativeOnly) { _%> 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | <%_ } else { _%> 12 | 13 | <%_ } _%> 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | <%_ if (!usingTS) { _%> 24 | <%# -------------------- Is Not Using TypeScript -------------------- -%> 25 | 44 | <%_ } else { _%> 45 | <%# -------------------- Is Using TypeScript -------------------- -%> 46 | 64 | <%_ } _%> 65 | 66 | <%_ if (rootOptions.cssPreprocessor) { _%> 67 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass' ) { _%> 68 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 69 | 81 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 82 | <%# -------------------- IS Using stylus -------------------- -%> 83 | 94 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 95 | <%# -------------------- IS Using Less -------------------- -%> 96 | 108 | <%_ } _%> 109 | <%_ } else { _%> 110 | <%# -------------------- IS Using standard CSS -------------------- -%> 111 | 123 | <%_ } _%> -------------------------------------------------------------------------------- /generator/templates/vue-sfc-template.vue: -------------------------------------------------------------------------------- 1 | <%_ if (rootOptions.router) { _%> 2 | <%# -------------------- IS Using vue-router -------------------- -%> 3 | <%_ if (!options.isNativeOnly) { _%> 4 | 5 | 6 | <%_ } else { _%> 7 | 8 | <%_ } _%> 9 | <%_ } else { _%> 10 | <%# -------------------- IS NOT Using vue-router -------------------- -%> 11 | <%_ if (!options.isNativeOnly) { _%> 12 | 13 | 14 | <%_ } else { _%> 15 | 16 | <%_ } _%> 17 | <%_ } _%> 18 | <%_ if (!usingTS && rootOptions.router) { _%> 19 | <%# -------------------- IS NOT Using TypeScript AND IS Using vue-router -------------------- -%> 20 | <%# Remove this line and Uncomment the next to use script tag - Prettier formatting bug removes all script tags if these are left in -%> 21 | <%# -%> 22 | <%_ } else if (!usingTS && !rootOptions.router) { _%> 23 | <%# -------------------- IS NOT Using TypeScript AND IS NOT Using vue-router -------------------- -%> 24 | <%# Remove this line and Uncomment the next to use script tag - Prettier formatting bug removes all script tags if these are left in -%> 25 | <%# -%> 26 | <%_ } else if (usingTS && rootOptions.router) { _%> 27 | <%# -------------------- IS Using TypeScript AND IS Using vue-router -------------------- -%> 28 | <%# -%> 29 | <%_ } else if (usingTS && !rootOptions.router) { _%> 30 | <%# -------------------- IS Using TypeScript AND IS NOT Using vue-router -------------------- -%> 31 | <%# -%> 32 | <%_ } else { _%> 33 | <%# -------------------- don't do anything -------------------- -%> 34 | <%_ } _%> 35 | 36 | <%_ if (rootOptions.cssPreprocessor) { _%> 37 | <%_ if (rootOptions.cssPreprocessor == 'sass' || rootOptions.cssPreprocessor == 'scss' || rootOptions.cssPreprocessor == 'dart-sass') { _%> 38 | <%# -------------------- IS Using sass, scss OR dart-sass -------------------- -%> 39 | 41 | 43 | <%_ } else if (rootOptions.cssPreprocessor == 'stylus') { _%> 44 | <%# -------------------- IS Using stylus -------------------- -%> 45 | 47 | 49 | <%_ } else if (rootOptions.cssPreprocessor == 'less') { _%> 50 | <%# -------------------- IS Using Less -------------------- -%> 51 | 53 | 55 | <%_ } _%> 56 | <%_ } else { _%> 57 | <%# -------------------- IS Using standard CSS -------------------- -%> 58 | 60 | 62 | <%_ } _%> 63 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | /* eslint-disable import/no-extraneous-dependencies */ 3 | const { relative, resolve, sep, join } = require('path'); 4 | const fs = require('fs-extra'); 5 | 6 | const webpack = require('webpack'); 7 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 8 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 9 | const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); 10 | const TerserPlugin = require('terser-webpack-plugin'); 11 | 12 | const VueLoaderPlugin = require('vue-loader/lib/plugin'); 13 | const NsVueTemplateCompiler = require('nativescript-vue-template-compiler'); 14 | 15 | const nsWebpack = require('nativescript-dev-webpack'); 16 | const nativescriptTarget = require('nativescript-dev-webpack/nativescript-target'); 17 | const { NativeScriptWorkerPlugin } = require('nativescript-worker-loader/NativeScriptWorkerPlugin'); 18 | 19 | const hashSalt = Date.now().toString(); 20 | 21 | const DefinePlugin = require('webpack/lib/DefinePlugin'); 22 | 23 | // // // TO BE REMOVED SOON 24 | // // // // eslint-disable-next-line prefer-destructuring 25 | // // // const PlatformFSPlugin = nsWebpack.PlatformFSPlugin; 26 | // // // // eslint-disable-next-line prefer-destructuring 27 | // // // const WatchStateLoggerPlugin = nsWebpack.WatchStateLoggerPlugin; 28 | 29 | const resolveExtensionsOptions = { 30 | web: ['*', '.ts', '.tsx', '.js', '.jsx', '.vue', '.json', '.scss', '.styl', '.less', '.css'], 31 | android: [ 32 | '*', 33 | '.native.ts', 34 | '.android.ts', 35 | '.ts', 36 | '.native.js', 37 | '.android.js', 38 | '.js', 39 | '.native.vue', 40 | '.android.vue', 41 | '.vue', 42 | '.json', 43 | '.native.scss', 44 | '.android.scss', 45 | '.scss', 46 | '.native.styl', 47 | '.android.styl', 48 | '.styl', 49 | '.native.less', 50 | '.android.less', 51 | '.less', 52 | '.native.css', 53 | '.android.css', 54 | '.css' 55 | ], 56 | ios: [ 57 | '*', 58 | '.native.ts', 59 | '.ios.ts', 60 | '.ts', 61 | '.native.js', 62 | '.ios.js', 63 | '.js', 64 | '.native.vue', 65 | '.ios.vue', 66 | '.vue', 67 | '.json', 68 | '.native.scss', 69 | '.ios.scss', 70 | '.scss', 71 | '.native.styl', 72 | '.ios.styl', 73 | '.styl', 74 | '.native.less', 75 | '.ios.less', 76 | '.less', 77 | '.native.css', 78 | '.ios.css', 79 | '.css' 80 | ] 81 | }; 82 | 83 | const getBlockRegex = (tag, mode) => { 84 | return `^((<${tag})(.+\\b${mode}\\b))([\\s\\S]*?>)[\\s\\S]*?(<\\/${tag}>)`; 85 | // Rejected code from PR #26 as the issue could not be reproduced. Leaving it in commented out in case we need to look at this again in the future. 86 | // return `^((<${tag})(.+\\b${mode}\\b))([\\s\\S]*?>)((?=[\\s\\S]*?<${tag}.+\\b${mode === 'web' ? 'native' : 'web'}\\b[\\s\\S]*?>)([\\s\\S]+(?=[\\s\\S]*?<${tag}.+\\b${mode === 'web' ? 'native' : 'web'}\\b[\\s\\S]*?>))|([\\s\\S]+<\\/${tag}>))`; 87 | }; 88 | 89 | module.exports = (api, projectOptions) => { 90 | let env = new Object(); 91 | let flags = new Array(); 92 | 93 | const addOption = (all, current) => { 94 | all[current] = true; 95 | return all; 96 | }; 97 | 98 | // console.log('api.service.mode - ', api.service.mode); 99 | 100 | // are we using the vue cli or not and if so are we passing in the correct options 101 | if (api && api.service.mode && api.service.mode.indexOf('.') !== -1) { 102 | // will convert the --mode options into an array for later use 103 | flags = api.service.mode.split('.'); 104 | // console.log('vue cli - flags - ', flags); 105 | } else { 106 | // get the --env command line options and put them in the env variable 107 | const [, , ...processArgs] = process.argv; 108 | flags = [...processArgs].filter((f) => f.startsWith('--env.')).map((f) => f.substring(6)); 109 | 110 | // in the rare event that tns and vue-cli get things mixed up and try and load the production 111 | // environment and development environment at the same time, we will default to loading 112 | // the development environment. you will generally see this when using something like 113 | // fastlane and having it do a 'tns prepare' as you are prepping to package and upload 114 | // your app to the app store. For internal testing you may want to package a development 115 | // version of the app, but `tns prepare` will try and load the production environmental variables 116 | if(flags.includes('development') && flags.includes('production')) { 117 | const index = flags.findIndex((obj) => obj === 'production') 118 | if(index > -1) { 119 | flags.splice(index, 1); 120 | } 121 | } 122 | 123 | // console.log('tns cli - flags - ', flags); 124 | 125 | // take advantage of the vue cli api to load the --env items into process.env. 126 | // we are filtering out the items, by catching the '=' sign, brought in from nsconfig.json as those don't need loaded into process.env 127 | // we are also filtering out 'sourceMap' which will appear with 'tns debug' as well as 'hmr' and 'uglify' 128 | // the goal here is to figure out exactly what environmental variables to load 129 | const mode = flags.filter((o) => !o.includes('=') && !o.includes('sourceMap') && !o.includes('hmr') && !o.includes('uglify')).join('.'); 130 | // console.log('loadEnv - ', mode); 131 | api.service.loadEnv(mode); 132 | 133 | } 134 | 135 | // setup the traditional {N} webpack 'env' variable 136 | env = flags.reduce(addOption, {}); 137 | // console.log('env - ', env); 138 | 139 | let platform = env && ((env.android && 'android') || (env.ios && 'ios') || (env.web && 'web')); 140 | // console.log('platform - ', platform); 141 | 142 | if (!platform) { 143 | // TNS (iOS/Android) always sets platform, so assume platform = 'web' & Vue-CLI glitch of loosing .env options in the UI 144 | platform = 'web'; 145 | // --> TO BE DELETED SOON 146 | // throw new Error('You need to provide a target platform!'); 147 | } 148 | 149 | const projectRoot = api.service.context; 150 | const appMode = platform === 'android' ? 'native' : platform === 'ios' ? 'native' : 'web'; 151 | 152 | // setup output directory depending on if we're building for web or native 153 | projectOptions.outputDir = join(projectRoot, appMode === 'web' ? 'dist' : nsWebpack.getAppPath(platform, projectRoot)); 154 | 155 | return appMode === 'web' ? webConfig(api, projectOptions, env, projectRoot) : nativeConfig(api, projectOptions, env, projectRoot, platform); 156 | }; 157 | 158 | const resolveExtensions = (config, ext) => { 159 | config.resolve.extensions.add(ext).end(); 160 | }; 161 | 162 | const nativeConfig = (api, projectOptions, env, projectRoot, platform) => { 163 | console.log('starting nativeConfig'); 164 | process.env.VUE_CLI_TARGET = 'nativescript'; 165 | const isNativeOnly = !fs.pathExistsSync(resolve(projectRoot, 'src')); 166 | const tsconfigFileName = 'tsconfig.json'; 167 | 168 | const appComponents = ['tns-core-modules/ui/frame', 'tns-core-modules/ui/frame/activity']; 169 | 170 | const platforms = ['ios', 'android']; 171 | 172 | // Default destination inside platforms//... 173 | const dist = projectOptions.outputDir; 174 | const appResourcesPlatformDir = platform === 'android' ? 'Android' : 'iOS'; 175 | 176 | const { 177 | // The 'appPath' and 'appResourcesPath' values are fetched from 178 | // the nsconfig.json configuration file 179 | // when bundling with `tns run android|ios --bundle`. 180 | appPath = isNativeOnly === true ? 'app' : 'src', 181 | appResourcesPath = join(appPath, 'App_Resources'), 182 | 183 | // You can provide the following flags when running 'tns run android|ios' 184 | snapshot, // --env.snapshot 185 | production, // --env.production 186 | report, // --env.report 187 | hmr, // --env.hmr 188 | sourceMap, // -env.sourceMap 189 | hiddenSourceMap, // -env.HiddenSourceMap 190 | unitTesting, // -env.unittesting 191 | verbose // --env.verbose 192 | } = env; 193 | 194 | const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap; 195 | const externals = nsWebpack.getConvertedExternals(env.externals); 196 | 197 | // // // // --env.externals 198 | // // // const externals = (env.externals || []).map((e) => { 199 | // // // return new RegExp(e + '.*'); 200 | // // // }); 201 | 202 | const mode = production ? 'production' : 'development'; 203 | 204 | const appFullPath = resolve(projectRoot, appPath); 205 | const appResourcesFullPath = resolve(projectRoot, appResourcesPath); 206 | 207 | // const entryModule = nsWebpack.getEntryModule(appFullPath); 208 | const entryModule = nsWebpack.getEntryModule(appFullPath, platform); 209 | const entryPath = `.${sep}${entryModule}`; 210 | const entries = { bundle: entryPath }; 211 | const areCoreModulesExternal = Array.isArray(env.externals) && env.externals.some((e) => e.indexOf('tns-core-modules') > -1); 212 | // // if (platform === 'ios' ) { 213 | // // entries['tns_modules/tns-core-modules/inspector_modules'] = 'inspector_modules.js'; 214 | // // } 215 | if (platform === 'ios' && !areCoreModulesExternal) { 216 | entries['tns_modules/tns-core-modules/inspector_modules'] = 'inspector_modules'; 217 | } 218 | 219 | console.log(`Bundling application for entryPath ${entryPath}...`); 220 | 221 | let sourceMapFilename = nsWebpack.getSourceMapFilename(hiddenSourceMap, __dirname, dist); 222 | 223 | const itemsToClean = [`${dist}/**/*`]; 224 | if (platform === 'android') { 225 | itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'src', 'main', 'assets', 'snapshots')}`); 226 | itemsToClean.push(`${join(projectRoot, 'platforms', 'android', 'app', 'build', 'configurations', 'nativescript-android-snapshot')}`); 227 | } 228 | 229 | nsWebpack.processAppComponents(appComponents, platform); 230 | 231 | api.chainWebpack((config) => { 232 | config 233 | .mode(mode) 234 | .context(appFullPath) 235 | .devtool(hiddenSourceMap ? 'hidden-source-map' : sourceMap ? 'inline-source-map' : 'none') 236 | .end(); 237 | 238 | config.externals(externals).end(); 239 | 240 | config 241 | .watchOptions({ 242 | ignored: [ 243 | appResourcesFullPath, 244 | // Don't watch hidden files 245 | '**/.*' 246 | ] 247 | }) 248 | .target(nativescriptTarget) 249 | .end(); 250 | 251 | config.entryPoints // clear out old config.entryPoints and install new 252 | .clear() 253 | .end() 254 | .entry('bundle') 255 | // .entry(entries) 256 | .add(entryPath) 257 | .end(); 258 | 259 | // clear out old config.output and install new 260 | config.output.clear().end(); 261 | 262 | config.output 263 | .pathinfo(false) 264 | .path(dist) 265 | .sourceMapFilename(sourceMapFilename) 266 | .libraryTarget('commonjs2') 267 | .filename(`[name].js`) 268 | .globalObject('global') 269 | .hashSalt(hashSalt) 270 | .end(); 271 | 272 | // next several use the resolveExtension function to easily 273 | // add in resolve.extensions from an object array const 274 | // or directly from a string 275 | config.resolve.extensions.clear(); 276 | 277 | if (platform === 'android') { 278 | for (let ext of resolveExtensionsOptions.android) { 279 | resolveExtensions(config, ext); 280 | } 281 | } else { 282 | for (let ext of resolveExtensionsOptions.ios) { 283 | resolveExtensions(config, ext); 284 | } 285 | } 286 | 287 | // delete these out. we'll add them back in, but we do it 288 | // this way to ensure that we get the exact path we need. 289 | config.resolve.modules.delete('node_modules'); 290 | config.resolve.modules.delete(resolve(projectRoot, 'node_modules')); 291 | 292 | config.resolve.modules // Resolve {N} system modules from tns-core-modules 293 | .add(resolve(projectRoot, 'node_modules/tns-core-modules')) 294 | .add(resolve(projectRoot, 'node_modules')) 295 | .add('node_modules/tns-core-modules') 296 | .add('node_modules') 297 | .end() 298 | .alias.delete('vue$') 299 | .delete('@') 300 | .set('~', appFullPath) 301 | .set('@', appFullPath) 302 | .set('src', api.resolve('src')) 303 | .set('app', isNativeOnly ? api.resolve('app') : api.resolve('src')) 304 | .set('assets', resolve(isNativeOnly ? api.resolve('app') : api.resolve('src'), 'assets')) 305 | .set('components', resolve(isNativeOnly ? api.resolve('app') : api.resolve('src'), 'components')) 306 | .set('fonts', resolve(isNativeOnly ? api.resolve('app') : api.resolve('src'), 'fonts')) 307 | .set('styles', resolve(isNativeOnly ? api.resolve('app') : api.resolve('src'), 'styles')) 308 | .set('root', projectRoot) 309 | .set('vue$', 'nativescript-vue') 310 | .set('vue', 'nativescript-vue') 311 | .end() 312 | .symlinks(true) // don't resolve symlinks to symlinked modules 313 | .end(); 314 | 315 | config.resolveLoader 316 | .symlinks(false) // don't resolve symlinks to symlinked modules 317 | .end(); 318 | 319 | config.node 320 | .set('http', false) 321 | .set('timers', false) 322 | .set('setImmediate', false) 323 | .set('fs', 'empty') 324 | .set('__dirname', false) 325 | .end(); 326 | 327 | config.optimization.runtimeChunk('single'), // --> NOT WORKING YET 328 | config.optimization 329 | .splitChunks({ 330 | cacheGroups: { 331 | vendor: { 332 | name: 'vendor', 333 | chunks: 'all', 334 | test: (module) => { 335 | const moduleName = module.nameForCondition ? module.nameForCondition() : ''; 336 | return /[\\/]node_modules[\\/]/.test(moduleName) || appComponents.some((comp) => comp === moduleName); 337 | }, 338 | enforce: true 339 | } 340 | } 341 | }) 342 | .end(); 343 | 344 | config.optimization.minimize(Boolean(production)); 345 | config.optimization 346 | .minimizer('terser') 347 | .use(TerserPlugin, [{ 348 | parallel: true, 349 | cache: true, 350 | sourceMap: isAnySourceMapEnabled, 351 | terserOptions: { 352 | output: { 353 | comments: false, 354 | semicolons: !isAnySourceMapEnabled 355 | }, 356 | compress: { 357 | // The Android SBG has problems parsing the output 358 | // when these options are enabled 359 | collapse_vars: platform !== 'android', 360 | sequences: platform !== 'android' 361 | }, 362 | keep_fnames: true 363 | } 364 | }]) 365 | .end(); 366 | 367 | config.module 368 | .rule('native-loaders') 369 | // .test(new RegExp(entryPath)) --> OLD ENTRY - TO BE REMOVED 370 | .test(new RegExp(nsWebpack.getEntryPathRegExp(appFullPath, entryPath + '.(js|ts)'))) 371 | .use('nativescript-dev-webpack/bundle-config-loader') 372 | .loader('nativescript-dev-webpack/bundle-config-loader') 373 | .options({ 374 | registerPages: true, // applicable only for non-angular apps 375 | loadCss: !snapshot, // load the application css if in debug mode 376 | unitTesting, 377 | appFullPath, 378 | projectRoot, 379 | ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform) 380 | }) 381 | .end(); 382 | 383 | config.when(platform === 'android', (config) => { 384 | config.module 385 | .rule('native-loaders') 386 | .use('nativescript-dev-webpack/android-app-components-loader') 387 | .loader('nativescript-dev-webpack/android-app-components-loader') 388 | .options({ 389 | modules: appComponents 390 | }) 391 | .before('nativescript-dev-webpack/bundle-config-loader') 392 | .end(); 393 | }); 394 | 395 | // delete the vue loader rule and rebuild it 396 | config.module.rules.delete('vue'); 397 | config.module 398 | .rule('vue') 399 | .test(/\.vue$/) 400 | .use('vue-loader') 401 | .loader('vue-loader') 402 | .options( 403 | Object.assign( 404 | { 405 | compiler: NsVueTemplateCompiler 406 | }, 407 | {} 408 | ) 409 | ) 410 | .before('string-replace-loader') 411 | .end() 412 | .use('string-replace-loader') 413 | .loader('string-replace-loader') 414 | .options( 415 | Object.assign( 416 | { 417 | multiple: [ 418 | { 419 | search: getBlockRegex('template', 'web'), 420 | replace: '', 421 | flags: 'gim', 422 | strict: false 423 | }, 424 | { 425 | search: getBlockRegex('script', 'web'), 426 | replace: '', 427 | flags: 'gim', 428 | strict: false 429 | }, 430 | { 431 | search: getBlockRegex('style', 'web'), 432 | replace: '', 433 | flags: 'gim', 434 | strict: false 435 | } 436 | ] 437 | }, 438 | {} 439 | ) 440 | ) 441 | .end(); 442 | 443 | // delete the js loader rule and rebuil it 444 | config.module.rules.delete('js'); 445 | config.module 446 | .rule('js') 447 | .test(/\.js$/) 448 | .use('babel-loader') 449 | .loader('babel-loader') 450 | .end(); 451 | 452 | config.module 453 | .rule('jsx') 454 | .test(/\.jsx$/) 455 | .use('babel-loader') 456 | .loader('babel-loader') 457 | .end(); 458 | 459 | // only adjust ts-loaders when we're using typescript in the project 460 | if (api.hasPlugin('typescript')) { 461 | config.module.rules.get('ts').uses.delete('cache-loader'); 462 | config.module.rules.get('ts').uses.delete('babel-loader'); 463 | if (mode === 'production') config.module.rules.get('ts').uses.delete('thread-loader'); 464 | 465 | const tsConfigOptions = config.module 466 | .rule('ts') 467 | .uses.get('ts-loader') 468 | .get('options'); 469 | 470 | tsConfigOptions.configFile = resolve(projectRoot, tsconfigFileName); 471 | 472 | (tsConfigOptions.appendTsSuffixTo = [/\.vue$/]), 473 | (tsConfigOptions.allowTsInNodeModules = true), 474 | (tsConfigOptions.compilerOptions = { 475 | declaration: false 476 | }); 477 | 478 | config.module 479 | .rule('ts') 480 | .test(/\.ts$/) 481 | .use('ts-loader') 482 | .loader('ts-loader') 483 | .options(Object.assign({}, tsConfigOptions)) 484 | .end(); 485 | 486 | config.module.rules.get('tsx').uses.delete('cache-loader'); 487 | config.module.rules.get('tsx').uses.delete('babel-loader'); 488 | if (mode === 'production') config.module.rules.get('tsx').uses.delete('thread-loader'); 489 | 490 | const tsxConfigOptions = config.module 491 | .rule('tsx') 492 | .uses.get('ts-loader') 493 | .get('options'); 494 | 495 | tsxConfigOptions.configFile = resolve(projectRoot, tsconfigFileName); 496 | (tsxConfigOptions.appendTsSuffixTo = [/\.vue$/]), 497 | (tsxConfigOptions.allowTsInNodeModules = true), 498 | (tsxConfigOptions.compilerOptions = { 499 | declaration: false 500 | }); 501 | 502 | config.module 503 | .rule('tsx') 504 | .test(/\.tsx$/) 505 | .use('ts-loader') 506 | .loader('ts-loader') 507 | .options(Object.assign({}, tsxConfigOptions)) 508 | .end(); 509 | } 510 | 511 | // remove most of the css rules and rebuild it for nativescript-vue 512 | config.module.rules.get('css').oneOfs.delete('vue-modules'); 513 | config.module.rules.get('css').oneOfs.delete('normal-modules'); 514 | config.module.rules.get('css').oneOfs.delete('vue'); 515 | config.module.rules 516 | .get('css') 517 | .oneOfs.get('normal') 518 | .uses.delete('extract-css-loader'); 519 | config.module.rules 520 | .get('css') 521 | .oneOfs.get('normal') 522 | .uses.delete('vue-style-loader'); 523 | // config.module.rules 524 | // .get('css') 525 | // .oneOfs.get('normal') 526 | // .uses.delete('postcss-loader'); 527 | config.module 528 | .rule('css') 529 | .oneOf('normal') 530 | .use('nativescript-dev-webpack/apply-css-loader') 531 | .loader('nativescript-dev-webpack/apply-css-loader') 532 | .before('css-loader') 533 | .end() 534 | .use('nativescript-dev-webpack/style-hot-loader') 535 | .loader('nativescript-dev-webpack/style-hot-loader') 536 | .before('nativescript-dev-webpack/apply-css-loader') 537 | .end() 538 | .use('css-loader') 539 | .loader('css-loader') 540 | .options( 541 | Object.assign( 542 | config.module 543 | .rule('css') 544 | .oneOf('normal') 545 | .uses.get('css-loader') 546 | .get('options'), 547 | { 548 | // minimize: false, 549 | url: false, 550 | importLoaders: 1 551 | } 552 | ) 553 | ) 554 | .end(); 555 | 556 | // remove most of the scss rules and rebuild it for nativescript-vue 557 | config.module.rules.get('scss').oneOfs.delete('vue-modules'); 558 | config.module.rules.get('scss').oneOfs.delete('normal-modules'); 559 | config.module.rules.get('scss').oneOfs.delete('vue'); 560 | config.module.rules 561 | .get('scss') 562 | .oneOfs.get('normal') 563 | .uses.delete('extract-css-loader'); 564 | config.module.rules 565 | .get('scss') 566 | .oneOfs.get('normal') 567 | .uses.delete('vue-style-loader'); 568 | // config.module.rules 569 | // .get('scss') 570 | // .oneOfs.get('normal') 571 | // .uses.delete('postcss-loader'); 572 | config.module 573 | .rule('scss') 574 | .oneOf('normal') 575 | .use('nativescript-dev-webpack/apply-css-loader') 576 | .loader('nativescript-dev-webpack/apply-css-loader') 577 | .before('css-loader') 578 | .end() 579 | .use('nativescript-dev-webpack/style-hot-loader') 580 | .loader('nativescript-dev-webpack/style-hot-loader') 581 | .before('nativescript-dev-webpack/apply-css-loader') 582 | .end() 583 | .use('css-loader') 584 | .loader('css-loader') 585 | .options( 586 | Object.assign( 587 | config.module 588 | .rule('scss') 589 | .oneOf('normal') 590 | .uses.get('css-loader') 591 | .get('options'), 592 | { 593 | // minimize: false, 594 | url: false, 595 | // data: '$PLATFORM: ' + platform + ';' 596 | } 597 | ) 598 | ) 599 | .end() 600 | .use('sass-loader') 601 | .loader('sass-loader') 602 | .options( 603 | Object.assign( 604 | config.module 605 | .rule('scss') 606 | .oneOf('normal') 607 | .uses.get('sass-loader') 608 | .get('options'), 609 | { 610 | // minimize: false, 611 | // url: false, 612 | prependData: '$PLATFORM: ' + platform + ';' 613 | } 614 | ) 615 | ) 616 | .end(); 617 | 618 | // remove most of the sass rules and rebuild it for nativescript-vue 619 | config.module.rules.get('sass').oneOfs.delete('vue-modules'); 620 | config.module.rules.get('sass').oneOfs.delete('normal-modules'); 621 | config.module.rules.get('sass').oneOfs.delete('vue'); 622 | config.module.rules 623 | .get('sass') 624 | .oneOfs.get('normal') 625 | .uses.delete('extract-css-loader'); 626 | config.module.rules 627 | .get('sass') 628 | .oneOfs.get('normal') 629 | .uses.delete('vue-style-loader'); 630 | // config.module.rules 631 | // .get('sass') 632 | // .oneOfs.get('normal') 633 | // .uses.delete('postcss-loader'); 634 | config.module 635 | .rule('sass') 636 | .oneOf('normal') 637 | .use('nativescript-dev-webpack/apply-css-loader') 638 | .loader('nativescript-dev-webpack/apply-css-loader') 639 | .before('css-loader') 640 | .end() 641 | .use('nativescript-dev-webpack/style-hot-loader') 642 | .loader('nativescript-dev-webpack/style-hot-loader') 643 | .before('nativescript-dev-webpack/apply-css-loader') 644 | .end() 645 | .use('css-loader') 646 | .loader('css-loader') 647 | .options( 648 | Object.assign( 649 | config.module 650 | .rule('sass') 651 | .oneOf('normal') 652 | .uses.get('css-loader') 653 | .get('options'), 654 | { 655 | // minimize: false, 656 | url: false, 657 | // data: '$PLATFORM: ' + platform 658 | } 659 | ) 660 | ) 661 | .end() 662 | .use('sass-loader') 663 | .loader('sass-loader') 664 | .options( 665 | Object.assign( 666 | config.module 667 | .rule('sass') 668 | .oneOf('normal') 669 | .uses.get('sass-loader') 670 | .get('options'), 671 | { 672 | minimize: false, 673 | // url: false, 674 | prependData: '$PLATFORM: ' + platform 675 | } 676 | ) 677 | ) 678 | .end(); 679 | 680 | // remove most of the stylus rules and rebuild it for nativescript-vue 681 | config.module.rules.get('stylus').oneOfs.delete('vue-modules'); 682 | config.module.rules.get('stylus').oneOfs.delete('normal-modules'); 683 | config.module.rules.get('stylus').oneOfs.delete('vue'); 684 | config.module.rules 685 | .get('stylus') 686 | .oneOfs.get('normal') 687 | .uses.delete('vue-style-loader'); 688 | // config.module.rules 689 | // .get('stylus') 690 | // .oneOfs.get('normal') 691 | // .uses.delete('postcss-loader'); 692 | config.module 693 | .rule('stylus') 694 | .oneOf('normal') 695 | .use('nativescript-dev-webpack/apply-css-loader') 696 | .loader('nativescript-dev-webpack/apply-css-loader') 697 | .before('css-loader') 698 | .end() 699 | .use('nativescript-dev-webpack/style-hot-loader') 700 | .loader('nativescript-dev-webpack/style-hot-loader') 701 | .before('nativescript-dev-webpack/apply-css-loader') 702 | .end() 703 | .use('css-loader') 704 | .loader('css-loader') 705 | .options( 706 | Object.assign( 707 | config.module 708 | .rule('stylus') 709 | .oneOf('normal') 710 | .uses.get('css-loader') 711 | .get('options'), 712 | { 713 | // minimize: false, 714 | url: false 715 | } 716 | ) 717 | ) 718 | .end() 719 | .use('stylus-loader') 720 | .loader('stylus-loader') 721 | .options( 722 | Object.assign( 723 | config.module 724 | .rule('stylus') 725 | .oneOf('normal') 726 | .uses.get('stylus-loader') 727 | .get('options'), 728 | { 729 | minimize: false, 730 | url: false 731 | } 732 | ) 733 | ) 734 | .end(); 735 | 736 | // remove most of the less rules and rebuild it for nativescript-vue 737 | config.module.rules.get('less').oneOfs.delete('vue-modules'); 738 | config.module.rules.get('less').oneOfs.delete('normal-modules'); 739 | config.module.rules.get('less').oneOfs.delete('vue'); 740 | config.module.rules 741 | .get('less') 742 | .oneOfs.get('normal') 743 | .uses.delete('vue-style-loader'); 744 | // config.module.rules 745 | // .get('less') 746 | // .oneOfs.get('normal') 747 | // .uses.delete('postcss-loader'); 748 | config.module 749 | .rule('less') 750 | .oneOf('normal') 751 | .use('nativescript-dev-webpack/apply-css-loader') 752 | .loader('nativescript-dev-webpack/apply-css-loader') 753 | .before('css-loader') 754 | .end() 755 | .use('nativescript-dev-webpack/style-hot-loader') 756 | .loader('nativescript-dev-webpack/style-hot-loader') 757 | .before('nativescript-dev-webpack/apply-css-loader') 758 | .end() 759 | .use('css-loader') 760 | .loader('css-loader') 761 | .options( 762 | Object.assign( 763 | config.module 764 | .rule('less') 765 | .oneOf('normal') 766 | .uses.get('css-loader') 767 | .get('options'), 768 | { 769 | // minimize: false, 770 | url: false 771 | } 772 | ) 773 | ) 774 | .end() 775 | .use('less-loader') 776 | .loader('less-loader') 777 | .options( 778 | Object.assign( 779 | config.module 780 | .rule('less') 781 | .oneOf('normal') 782 | .uses.get('less-loader') 783 | .get('options'), 784 | { 785 | // minimize: false, 786 | url: false 787 | } 788 | ) 789 | ) 790 | .end(); 791 | 792 | // // TO DO 793 | // // Needs to be added and converted to webpack Chain 794 | // if (unitTesting) { 795 | // config.module.rules.push( 796 | // { 797 | // test: /-page\.js$/, 798 | // use: "nativescript-dev-webpack/script-hot-loader" 799 | // }, 800 | // { 801 | // test: /\.(html|xml)$/, 802 | // use: "nativescript-dev-webpack/markup-hot-loader" 803 | // }, 804 | 805 | // { test: /\.(html|xml)$/, use: "nativescript-dev-webpack/xml-namespace-loader" } 806 | // ); 807 | // } 808 | 809 | // delete these rules that come standard with CLI 3 810 | // need to look at adding these back in after evaluating impact 811 | config.module.rules.delete('images').end(); 812 | 813 | // only delete the plugin if we aren't calling for HMR 814 | if (!env.hmr) { 815 | config.plugins.delete('hmr'); 816 | } 817 | 818 | // delete these plugins that come standard with CLI 3 819 | config.plugins.delete('html'); 820 | config.plugins.delete('preload'); 821 | config.plugins.delete('prefetch'); 822 | config.plugins.delete('pwa'); 823 | config.plugins.delete('progress'); 824 | config.plugins.delete('case-sensitive-paths'); 825 | config.plugins.delete('friendly-errors'); 826 | config.plugins.delete('no-emit-on-errors'); 827 | config.plugins.delete('copy').end(); 828 | 829 | if (mode === 'production') { 830 | config.plugins.delete('extract-css'); 831 | config.plugins.delete('optimize-css'); 832 | config.plugins.delete('hash-module-ids'); 833 | config.plugins.delete('named-chunks'); 834 | } 835 | 836 | // create new plugins 837 | config 838 | .plugin('vue-loader') 839 | .use(VueLoaderPlugin, []) 840 | .end(); 841 | 842 | // Define useful constants like TNS_WEBPACK 843 | // Merge DefinePlugin options that come in native from CLI 3 844 | config 845 | .plugin('define') 846 | .use(DefinePlugin, [ 847 | Object.assign(config.plugin('define').get('args')[0], { 848 | 'global.TNS_WEBPACK': 'true', 849 | TNS_ENV: JSON.stringify(mode), 850 | process: 'global.process' 851 | }) 852 | ]) 853 | .end(); 854 | 855 | // Remove all files from the out dir. 856 | config 857 | .plugin('clean') 858 | .use(CleanWebpackPlugin, [ 859 | itemsToClean, 860 | { verbose: !!verbose } 861 | // join(dist, '/**/*'), 862 | // { 863 | // root: dist 864 | // } 865 | ]) 866 | .end(); 867 | 868 | // Copy native app resources to out dir. 869 | // only if doing a full build (tns run/build) and not previewing (tns preview) 870 | if (!externals || externals.length === 0) { 871 | config 872 | .plugin('copy-native-resources') 873 | .use(CopyWebpackPlugin, [ 874 | [ 875 | { 876 | from: `${appResourcesFullPath}/${appResourcesPlatformDir}`, 877 | to: `${dist}/App_Resources/${appResourcesPlatformDir}`, 878 | context: projectRoot 879 | } 880 | ] 881 | ]) 882 | .end(); 883 | } 884 | 885 | // Copy assets to the out dir. 886 | config 887 | .plugin('copy-assets') 888 | .use(CopyWebpackPlugin, [ 889 | [ 890 | { 891 | from: { 892 | glob: 'fonts/**' 893 | } 894 | }, 895 | { 896 | from: { 897 | glob: '**/*.+(jpg|png)' 898 | } 899 | }, 900 | { 901 | from: { 902 | glob: 'assets/**/*' 903 | } 904 | } 905 | ], 906 | { 907 | context: resolve(isNativeOnly === true ? appFullPath : api.resolve('src')), 908 | ignore: [`${relative(appPath, appResourcesFullPath)}/**`] 909 | } 910 | ]) 911 | .end(); 912 | 913 | // Generate a bundle starter script and activate it in package.json 914 | config 915 | .plugin('generate-bundle-starter') 916 | .use(nsWebpack.GenerateBundleStarterPlugin, [ 917 | // // // ['./vendor', './bundle'] --> TO BE DELETED SOON 918 | 919 | // Don't include `runtime.js` when creating a snapshot. The plugin 920 | // configures the WebPack runtime to be generated inside the snapshot 921 | // module and no `runtime.js` module exist. 922 | (snapshot ? [] : ['./runtime']).concat(['./vendor', './bundle']) 923 | ]) 924 | .end(); 925 | 926 | // For instructions on how to set up workers with webpack 927 | // check out https://github.com/nativescript/worker-loader 928 | config 929 | .plugin('nativescript-worker') 930 | .use(NativeScriptWorkerPlugin, []) 931 | .end(); 932 | 933 | config 934 | .plugin('platform-FS') 935 | .use(nsWebpack.PlatformFSPlugin, [ 936 | { 937 | platform, 938 | platforms 939 | } 940 | ]) 941 | .end(); 942 | 943 | // Does IPC communication with the {N} CLI to notify events when running in watch mode. 944 | config 945 | .plugin('watch-state-logger') 946 | .use(nsWebpack.WatchStateLoggerPlugin, []) 947 | .end(); 948 | 949 | // Another only do this if we're using typescript. this code could have been put 950 | // with the ts-loader section but left it here near the rest of the plugin config 951 | if (api.hasPlugin('typescript')) { 952 | // Next section is weird as we have to copy the plugin's config, edit the copy 953 | // delete the plugin and then add the plugin back in with the saved config. 954 | // This is all because webpack-chain cannot access the 'tslint' option of the plugin 955 | // directly to edit it. 956 | const forTSPluginConfig = config.plugin('fork-ts-checker').get('args')[0]; 957 | 958 | forTSPluginConfig.tsconfig = resolve(projectRoot, tsconfigFileName); 959 | forTSPluginConfig.tslint = fs.pathExistsSync(resolve(projectRoot, 'tslint.json')) ? resolve(projectRoot, 'tslint.json') : false; 960 | forTSPluginConfig.checkSyntacticErrors = false; 961 | 962 | config.plugins.delete('fork-ts-checker').end(); 963 | 964 | config 965 | .plugin('fork-ts-checker') 966 | .use(require('fork-ts-checker-webpack-plugin'), [forTSPluginConfig]) 967 | .end(); 968 | } 969 | 970 | // the next several items are disabled as they are mirrored from the nativescript-dev-webpack 971 | // project. Need to figure out how to integrate some of that projects cli ability into this one. 972 | config.when(report, (config) => { 973 | config 974 | .plugin('bundle-analyzer') 975 | .use(BundleAnalyzerPlugin, [ 976 | { 977 | analyzerMode: 'static', 978 | openAnalyzer: false, 979 | generateStatsFile: true, 980 | reportFilename: resolve(projectRoot, 'report', `report.html`), 981 | statsFilename: resolve(projectRoot, 'report', `stats.json`) 982 | } 983 | ]) 984 | .end(); 985 | }); 986 | 987 | config.when(snapshot, (config) => { 988 | config 989 | .plugin('snapshot') 990 | .use(nsWebpack.NativeScriptSnapshotPlugin, [ 991 | { 992 | chunk: 'vendor', 993 | requireModules: ['tns-core-modules/bundle-entry-points'], 994 | projectRoot, 995 | webpackConfig: config 996 | } 997 | ]) 998 | .end(); 999 | }); 1000 | }); 1001 | }; 1002 | 1003 | const webConfig = (api, projectOptions, env, projectRoot) => { 1004 | console.log('starting webConfig'); 1005 | const dist = projectOptions.outputDir; 1006 | 1007 | const { 1008 | // The 'appPath' and 'appResourcesPath' values are fetched from 1009 | // the nsconfig.json configuration file 1010 | // when bundling with `tns run android|ios --bundle`. 1011 | appPath = 'src', 1012 | appResourcesPath = join(appPath, 'App_Resources'), 1013 | 1014 | // You can provide the following flags when running 'tns run android|ios' 1015 | // snapshot, // --env.snapshot 1016 | production // --env.production 1017 | // report, // --env.report 1018 | // hmr // --env.hmr 1019 | } = env; 1020 | 1021 | const mode = production ? 'production' : 'development'; 1022 | const appResourcesFullPath = resolve(projectRoot, appResourcesPath); 1023 | 1024 | api.chainWebpack((config) => { 1025 | config.entry('app').clear(); 1026 | config.entry('app').add(resolve(api.resolve('src'), 'main')); 1027 | 1028 | config.output.path(dist).end(); 1029 | 1030 | config.resolve.alias 1031 | .delete('@') 1032 | .set('@', api.resolve('src')) 1033 | .set('~', api.resolve('src')) 1034 | .set('src', api.resolve('src')) 1035 | .set('assets', resolve(api.resolve('src'), 'assets')) 1036 | .set('components', resolve(api.resolve('src'), 'components')) 1037 | .set('fonts', resolve(api.resolve('src'), 'fonts')) 1038 | .set('styles', resolve(api.resolve('src'), 'styles')) 1039 | .set('root', projectRoot) 1040 | .end(); 1041 | 1042 | config.resolve.extensions.clear(); 1043 | 1044 | for (let ext of resolveExtensionsOptions.web) { 1045 | resolveExtensions(config, ext); 1046 | } 1047 | 1048 | config.module 1049 | .rule('vue') 1050 | .use('cache-loader') 1051 | .loader('cache-loader') 1052 | .tap((options) => { 1053 | options.cacheDirectory = config.module 1054 | .rule('vue') 1055 | .uses.get('cache-loader') 1056 | .get('options').cacheDirectory; 1057 | return options; 1058 | }) 1059 | .end() 1060 | .use('vue-loader') 1061 | .loader('vue-loader') 1062 | .options( 1063 | Object.assign( 1064 | {}, 1065 | config.module 1066 | .rule('vue') 1067 | .uses.get('vue-loader') 1068 | .get('options') 1069 | ) 1070 | ) 1071 | .end() 1072 | .use('string-replace-loader') 1073 | .loader('string-replace-loader') 1074 | .options( 1075 | Object.assign( 1076 | { 1077 | multiple: [ 1078 | { 1079 | search: getBlockRegex('template', 'native'), 1080 | replace: '', 1081 | flags: 'gim', 1082 | strict: false 1083 | }, 1084 | { 1085 | search: getBlockRegex('script', 'native'), 1086 | replace: '', 1087 | flags: 'gim', 1088 | strict: false 1089 | }, 1090 | { 1091 | search: getBlockRegex('style', 'native'), 1092 | replace: '', 1093 | flags: 'gim', 1094 | strict: false 1095 | } 1096 | ] 1097 | }, 1098 | {} 1099 | ) 1100 | ) 1101 | .end(); 1102 | 1103 | const imageLoaderOptions = config.module 1104 | .rule('images') 1105 | .uses.get('url-loader') 1106 | .get('options'); 1107 | imageLoaderOptions.fallback.options.name = 'assets/[name][hash:8].[ext]'; 1108 | config.module.rules.delete('images'); 1109 | 1110 | config.module 1111 | .rule('images') 1112 | .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/) 1113 | .use('url-loader') 1114 | .loader('url-loader') 1115 | .options(imageLoaderOptions) 1116 | .end(); 1117 | 1118 | // // // // Define useful constants like TNS_WEBPACK 1119 | // // // // Merge DefinePlugin options that come in native from CLI 3 1120 | // // // config 1121 | // // // .plugin('define') 1122 | // // // .use(DefinePlugin, [ 1123 | // // // Object.assign(config.plugin('define').get('args')[0], { 1124 | // // // TNS_ENV: JSON.stringify(mode), 1125 | // // // TNS_APP_PLATFORM: JSON.stringify(process.env.VUE_APP_PLATFORM), 1126 | // // // TNS_APP_MODE: JSON.stringify(process.env.VUE_APP_MODE) 1127 | // // // }) 1128 | // // // ]) 1129 | // // // .end(); 1130 | 1131 | // Remove all files from the out dir. 1132 | config 1133 | .plugin('clean') 1134 | .use(CleanWebpackPlugin, [ 1135 | join(dist, '/**/*'), 1136 | { 1137 | root: dist 1138 | } 1139 | ]) 1140 | .end(); 1141 | 1142 | // Copy assets to out dir. Add your own globs as needed. 1143 | // if the project is native-only then we want to copy files 1144 | // from the app directory and not the src directory as at 1145 | // that point, the src directory should have been removed 1146 | // when the plugin was originally invoked. 1147 | config 1148 | .plugin('copy-assets') 1149 | .use(CopyWebpackPlugin, [ 1150 | [ 1151 | { 1152 | from: { 1153 | glob: 'fonts/**' 1154 | } 1155 | }, 1156 | { 1157 | from: { 1158 | glob: '**/*.+(jpg|png)' 1159 | } 1160 | }, 1161 | { 1162 | from: { 1163 | glob: 'assets/**/*', 1164 | ignore: ['**/*.+(jpg|png)'] 1165 | } 1166 | } 1167 | ], 1168 | { 1169 | context: resolve(api.resolve('src')), 1170 | ignore: [`${relative(appPath, appResourcesFullPath)}/**`] 1171 | } 1172 | ]) 1173 | .end(); 1174 | 1175 | // only adjust ts-loaders when we're using typescript in the project 1176 | if (api.hasPlugin('typescript')) { 1177 | const tsConfigOptions = config.module 1178 | .rule('ts') 1179 | .uses.get('ts-loader') 1180 | .get('options'); 1181 | 1182 | tsConfigOptions.configFile = resolve(projectRoot, 'tsconfig.json'); 1183 | 1184 | config.module 1185 | .rule('ts') 1186 | .test(/\.ts$/) 1187 | .use('ts-loader') 1188 | .loader('ts-loader') 1189 | .options(tsConfigOptions) 1190 | .end(); 1191 | 1192 | const tsxConfigOptions = config.module 1193 | .rule('ts') 1194 | .uses.get('ts-loader') 1195 | .get('options'); 1196 | 1197 | tsxConfigOptions.configFile = resolve(projectRoot, 'tsconfig.json'); 1198 | 1199 | config.module 1200 | .rule('tsx') 1201 | .test(/\.tsx$/) 1202 | .use('ts-loader') 1203 | .loader('ts-loader') 1204 | .options(tsxConfigOptions) 1205 | .end(); 1206 | 1207 | // Next section is weird as we have to copy the plugin's config, edit the copy 1208 | // delete the plugin and then add the plugin back in with the saved config. 1209 | // This is all because webpack chain cannot access the 'tslint' option of the plugin 1210 | // directly to edit it. 1211 | const forTSPluginConfig = config.plugin('fork-ts-checker').get('args')[0]; 1212 | 1213 | forTSPluginConfig.tsconfig = resolve(projectRoot, 'tsconfig.json'); 1214 | forTSPluginConfig.tslint = fs.pathExistsSync(resolve(projectRoot, 'tslint.json')) ? resolve(projectRoot, 'tslint.json') : false; 1215 | 1216 | config.plugins.delete('fork-ts-checker').end(); 1217 | 1218 | config 1219 | .plugin('fork-ts-checker') 1220 | .use(require('fork-ts-checker-webpack-plugin'), [forTSPluginConfig]) 1221 | .end(); 1222 | } 1223 | }); 1224 | }; 1225 | -------------------------------------------------------------------------------- /lib/scripts/webpack-maintenance.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const replace = require('replace-in-file'); 3 | 4 | const mode = process.argv[2]; 5 | 6 | if (mode === 'pre') Pre(); 7 | 8 | if (mode === 'post') Post(); 9 | 10 | function Pre() { 11 | console.log('copying CLI 3 version of webpack.config.js to project'); 12 | // setup string replacement options for webpack.config.js file 13 | const replaceOptions = { 14 | files: './webpack.config.js', 15 | from: './lib/Service', 16 | to: '@vue/cli-service/lib/Service' 17 | }; 18 | 19 | // copy the dynamic webpack config from the cli-service. 20 | fs.copyFile('./node_modules/@vue/cli-service/webpack.config.js', './webpack.config.js', (err) => { 21 | //console.error('copyFile Error occurred:', err); 22 | if (err) { 23 | console.error('copyFile Error occurred:', err); 24 | if (err) throw err; 25 | } 26 | 27 | // edit the file to correct a hard-coded path to be relative 28 | replace(replaceOptions, (err, changes) => { 29 | if (err) { 30 | console.error('replace Error occurred:', err); 31 | if (err) throw err; 32 | } 33 | }); 34 | }); 35 | } 36 | 37 | function Post() { 38 | console.log('starting Post'); 39 | if (fs.existsSync('./webpack.config.js')) { 40 | fs.unlink('./webpack.config.js', (err) => { 41 | if (err) throw err; 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/tslint.js: -------------------------------------------------------------------------------- 1 | // code taken from @vue/cli-plugin-typescript package 2 | 3 | module.exports = function lint(args = {}, api, silent) { 4 | const cwd = api.resolve('.'); 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | const globby = require('globby'); 8 | const tslint = require('tslint'); 9 | const ts = require('typescript'); 10 | /* eslint-disable-next-line node/no-extraneous-require */ 11 | const vueCompiler = require('vue-template-compiler'); 12 | const isVueFile = (file) => /\.vue(\.ts)?$/.test(file); 13 | 14 | const options = { 15 | fix: args['fix'] !== false, 16 | formatter: args.format || 'codeFrame', 17 | formattersDirectory: args['formatters-dir'], 18 | rulesDirectory: args['rules-dir'] 19 | }; 20 | 21 | // hack to make tslint --fix work for *.vue files: 22 | // we save the non-script parts to a cache right before 23 | // linting the file, and patch fs.writeFileSync to combine the fixed script 24 | // back with the non-script parts. 25 | // this works because (luckily) tslint lints synchronously. 26 | const vueFileCache = new Map(); 27 | const writeFileSync = fs.writeFileSync; 28 | 29 | const patchWriteFile = () => { 30 | fs.writeFileSync = (file, content, options) => { 31 | if (isVueFile(file)) { 32 | const parts = vueFileCache.get(path.normalize(file)); 33 | if (parts) { 34 | const { before, after } = parts; 35 | content = `${before}\n${content.trim()}\n${after}`; 36 | } 37 | } 38 | return writeFileSync(file, content, options); 39 | }; 40 | }; 41 | 42 | const restoreWriteFile = () => { 43 | fs.writeFileSync = writeFileSync; 44 | }; 45 | 46 | const parseTSFromVueFile = (file) => { 47 | const content = fs.readFileSync(file, 'utf-8'); 48 | const { script } = vueCompiler.parseComponent(content, { pad: 'line' }); 49 | if (script && /^tsx?$/.test(script.lang)) { 50 | vueFileCache.set(file, { 51 | before: content.slice(0, script.start), 52 | after: content.slice(script.end) 53 | }); 54 | return script; 55 | } 56 | }; 57 | 58 | const program = tslint.Linter.createProgram(api.resolve('tsconfig.json')); 59 | 60 | // patch getSourceFile for *.vue files 61 | // so that it returns the