Skip to content

Functional Code Sharing #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 61 commits into from
Mar 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
f023847
Initial Commit
jawa-the-hutt Nov 3, 2018
135f567
Merge pull request #1 from jawa-the-hutt/dev
jawa-the-hutt Nov 3, 2018
82fdcf5
Added prompt at invoke to check for new project;
jawa-the-hutt Nov 6, 2018
be2d407
Merge pull request #2 from jawa-the-hutt/dev
jawa-the-hutt Nov 6, 2018
7f7d035
integrated device based resolve extensions;
jawa-the-hutt Nov 9, 2018
224ea12
added forced babel.config.js setup. will overwrite existing.
jawa-the-hutt Nov 9, 2018
833de0c
Merge pull request #3 from jawa-the-hutt/dev
jawa-the-hutt Nov 9, 2018
d976b6d
Update prompts.js
jawa-the-hutt Nov 9, 2018
825dc2e
Update prompt.js
jawa-the-hutt Nov 9, 2018
ed8c5c9
Merge pull request #4 from jawa-the-hutt/dev
jawa-the-hutt Nov 9, 2018
023185d
can now render babel.config.js as needed
jawa-the-hutt Nov 9, 2018
62d35a0
finished simplying templating
jawa-the-hutt Nov 9, 2018
902b805
refactor several function names
jawa-the-hutt Nov 10, 2018
9845443
initial typescript integration - WIP
jawa-the-hutt Nov 10, 2018
2ae9e7a
further TypeScript work - WIP
jawa-the-hutt Nov 11, 2018
b3e3921
Typescript support is now working
jawa-the-hutt Nov 14, 2018
24005aa
removed some uneeded packages
jawa-the-hutt Nov 15, 2018
8369ab5
Typescript Support is complete
jawa-the-hutt Nov 15, 2018
ce10968
one last commit before branching again as a copy
jawa-the-hutt Nov 16, 2018
1df0593
Added NVW templates
Nov 16, 2018
5500c4e
Merge pull request #5 from jawa-the-hutt/feature/mylmz10-add-nvw-temp…
jawa-the-hutt Nov 16, 2018
0946629
Integrated NVW into project
jawa-the-hutt Nov 19, 2018
f463b71
Merge pull request #6 from jawa-the-hutt/dev-clean-seperation
jawa-the-hutt Nov 19, 2018
1e09842
Merge branch 'master' into dev
jawa-the-hutt Nov 19, 2018
8b2c393
Merge pull request #7 from jawa-the-hutt/dev
jawa-the-hutt Nov 19, 2018
ea813cb
delete with-nvw folder
jawa-the-hutt Nov 19, 2018
26ba92e
adjusted templates to have different css for NVW
jawa-the-hutt Nov 20, 2018
d9590ed
Adjusted NVW prompt to only show when Dual setup is chosen
jawa-the-hutt Nov 21, 2018
9564428
Merge pull request #8 from jawa-the-hutt/dev
jawa-the-hutt Nov 21, 2018
5796f8e
removed the without-nvw structure from the simple template
jawa-the-hutt Nov 21, 2018
559f49f
Almost a total rewrite of the plugin.
jawa-the-hutt Dec 16, 2018
22fb49c
Fixed issue with not being able to compile on IOS
jawa-the-hutt Dec 16, 2018
47c0a56
Merge pull request #11 from jawa-the-hutt/dev
jawa-the-hutt Dec 19, 2018
5002763
Dev to Master (#13)
jawa-the-hutt Jan 3, 2019
932c7ba
Upgrade project to {N} 5.1 (#14)
jawa-the-hutt Jan 7, 2019
b699c88
update install location for fork (#15)
jawa-the-hutt Jan 8, 2019
2f3cb2d
Added debug commands (#16)
jawa-the-hutt Jan 21, 2019
f07b117
Fix no-def eslint errors with TNS_APP_MODE and TNS_APP_PLATFORM vari…
msaelices Jan 31, 2019
b485595
Updated generic SFC template with latest structure
jawa-the-hutt Jan 31, 2019
2572f0d
Several Updates to template structures and styling (#21)
jawa-the-hutt Mar 3, 2019
cd60641
Fix bug for TS projects that don't use tslint (#22)
jawa-the-hutt Mar 4, 2019
d1fd1ca
Bug Fix: check for tslint before fork-ts-checker-webpack config
jawa-the-hutt Mar 4, 2019
750115b
Native Only improvements (#24)
jawa-the-hutt Mar 7, 2019
a6e285f
small template updates
jawa-the-hutt Mar 8, 2019
93d55af
bump babel deps up
jawa-the-hutt Mar 8, 2019
6b24dfc
use vue-cli service .env file pipeline for native
jawa-the-hutt Mar 11, 2019
318034d
adjust tns-ios version back to 5.2.0
jawa-the-hutt Mar 11, 2019
7295526
Fix tslint issue when invoking plugin with the `Native Only` option i…
msaelices Mar 11, 2019
6638db8
Merge pull request #25 from msaelices/dev
jawa-the-hutt Mar 11, 2019
60e1689
Fix a tslint race condition which happens if the tslint fixing proces…
msaelices Mar 12, 2019
61b522a
Merge pull request #26 from msaelices/dev
jawa-the-hutt Mar 12, 2019
af8e1a3
Wait until tslint.json is changed before executing tslint.
msaelices Mar 12, 2019
2df5c67
Fix the npm `run build:ios` and `npm run build:android` commands in T…
msaelices Mar 12, 2019
f43350a
Merge pull request #27 from msaelices/dev
jawa-the-hutt Mar 12, 2019
64fd9af
Ensure main.native.js ends with semicolon in order to pass the tslint…
msaelices Mar 12, 2019
9ac7efc
Fix typo in the README.md file.
msaelices Mar 13, 2019
e946c2b
Merge pull request #28 from msaelices/dev
jawa-the-hutt Mar 13, 2019
a5b0ba4
Fix `npm run build:ios` error related to that uglify-js does not supp…
msaelices Mar 13, 2019
e82f485
Bump 0.0.10 version.
msaelices Mar 13, 2019
84ba0bf
Merge pull request #29 from msaelices/dev
jawa-the-hutt Mar 13, 2019
4ff640e
Merge pull request #30 from jawa-the-hutt/dev
jawa-the-hutt Mar 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
generator/templates/
36 changes: 36 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module.exports = {
"root": true,
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended",
"@vue/airbnb",
"@vue/prettier"
],
"rules": {
"import/extensions": 0,
"global-require": 0,
"eol-last": 0,
"no-param-reassign": 0,
"object-curly-newline": 0,
"no-plusplus": 0,
"max-len": [
2,
{
"code": 160
}
],
"prefer-destructuring": [
2,
{
"object": true,
"array": false
}
]
},
"parserOptions": {
"parser": "babel-eslint"
}
}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/
node_modules/
.vscode
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
generator/templates/*
10 changes: 10 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"printWidth": 160,
"singleQuote": true,
"trailingComma": "none",
"tabWidth": 2,
"semicolons": true,
"bracketSpacing": true,
"arrowParens": "always",
"useTabs": false
}
243 changes: 242 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,242 @@
# nativescript-vue-cli-plugin
# nativescript-vue-cli-plugin

Nativescript-Vue Plugin for [vue-cli@3.0](https://github.com/vuejs/vue-cli)

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.

## Sharing logic in a single Web and Native capable component
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 (`<script>` block) but you want different templates for web and native, you can use the special `<template web>` and `<template native>`. Also, if you need define different styles you can use `<style web>` and `<style native>`.

An example of this would be the following Vue component:

```
<template web>
<div class="w-page">
<div class="w-container">
<img src="~/assets/logo.png" alt="logo" height="20%" width="20%">
<HelloWorld :msg="msg"/>
</div>
</div>
</template>
<template native>
<Page>
<ActionBar :title="navbarTitle"/>
<GridLayout rows="auto, auto">
<HelloWorld :msg="msg"/>
</GridLayout>
</Page>
</template>
<script>
import HelloWorld from '~/components/HelloWorld';
export default {
components: {
HelloWorld,
},
data() {
return {
navbarTitle: `App.${appMode}.vue`,
msg: `Mode=${appMode} and Platform=${process.env.VUE_APP_PLATFORM}`,
};
},
}
</script>
<style web>
w-page {
padding: 1rem;
}
</style>
<style native>
ActionBar {
color: red;
}
</style>
```

### Optional Separation of concerns for Web and Native SFC's
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` and `.css` files.

| File Type | Android __and__ IOS | Android only | IOS only | Web only |
| ---------- | ------------------- | --------------- | --------------- | --------------- |
| vue | *.native.vue | *.android.vue | *.ios.vue | *.vue |
| js | *.native.js | *.android.js | *.ios.js | *.js |
| ts | *.native.ts | *.android.ts | *.ios.ts | *.ts |
| scss | *.native.scss | *.android.scss | *.ios.scss | *.scss |
| css | *.native.css | *.android.css | *.ios.css | *.css |

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.

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.

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.

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.

## Sharing components and assets between Native and Web SFC's
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`.

## Install

If vue-cli 3 is not yet installed, first follow the instructions here: https://github.com/vuejs/vue-cli

**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).

Generate a project using vue-cli 3.0
```
vue create my-app
```

Before installing the Nativescript-Vue CLI 3 Plugin, make sure to commit or stash changes in case you need to revert.

To install the Nativescript-Vue CLI 3 Plugin...
```
cd my-app
npm install --save-dev git+https://github.com/jawa-the-hutt/vue-cli-plugin-nativescript-vue
vue invoke vue-cli-plugin-nativescript-vue
```

## Invocation Prompts
1. Enter a unique application identifier
* Accepting the default is fine for testing
2. Use HTML5 history mode? (Default: hash mode)
* Required parameter for the cli core generator when vue-router is used
3. Is this a brand new project? (Default: Yes)
* 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.
* 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.
4. Dual Native AND Web development experience or a Native only? (Default: Dual)
* 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`.
* 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`.
* 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.
5. What type of template do you want to start with? (Default: Simple)
* Simple is just a simple setup with a header and basic routing.
* [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.
* Sidebar (currently disabled), will allow you to start with a project that includes a fixed header and pop-out sidebar menu.
* We expect to add more templates in the future as use cases come up.

## Running the project
You will have several options in serving and building the project:
1. `npm run serve:web`
2. `npm run serve:android`
3. `npm run serve:ios`
4. `npm run build:web`
5. `npm run build:android`
6. `npm run build:ios`


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.

### Debugging your project
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.
1. `npm run debug:android`
2. `npm run debug:ios`

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).

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.

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.
```
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch on iOS",
"type": "nativescript",
"request": "launch",
"platform": "ios",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"watch": true,
"tnsArgs":[" --bundle --env.development cross-env-shell VUE_CLI_MODE=development.ios"]
},
{
"name": "Attach on iOS",
"type": "nativescript",
"request": "attach",
"platform": "ios",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"watch": false
},
{
"name": "Launch on Android",
"type": "nativescript",
"request": "launch",
"platform": "android",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"watch": true,
"tnsArgs":[" --bundle --env.development cross-env-shell VUE_CLI_MODE=development.android"]
},
{
"name": "Attach on Android",
"type": "nativescript",
"request": "attach",
"platform": "android",
"appRoot": "${workspaceRoot}",
"sourceMaps": true,
"watch": false
},
{
"type": "chrome",
"request": "launch",
"name": "web: chrome",
"url": "http://localhost:8080",
"webRoot": "${workspaceFolder}/src",
"breakOnLoad": true,
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/*"
}
},
]
}
```
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:
```
module.exports = {
chainWebpack: config => {
config
.devtool('inline-source-map')
}
}
```

### Previewing your Project
You should be able to use the NativeScript Playground and Preview Apps via the following npm statements:
1. `npm run preview:android`
2. `npm run preview:ios`

#### --env command line recognition
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.
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.

#### Webpack related information
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`.

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.

#### Inspecting the Webpack config
If you'd like to see what the webpack config is doing then you can run one of the following:

1. `vue inspect -- --env.android > out-android.js`
2. `vue inspect -- --env.ios > out-ios.js`
3. `vue inspect -- --env.web > out-web.js`

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.

#### Aliases
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:

| Alias | Native | Web |
| ---------- | --------------- | --------------- |
| ~ | /app | /src |
| @ | /app | /src |
| src | /src | /src |
| assets | /src/assets | /src/assets |
| components | /src/components | /src/components |
| fonts | /src/fonts | /src/fonts |
| styles | /src/styles | /src/styles |
| root | / | / |


## For TypeScript enabled projects
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.
32 changes: 32 additions & 0 deletions generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# nativescript-vue-cli-plugin - Generator Readme

Want to submit a PR for a new template? Read below.

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.

If you want to add additional templates to the plugin, then here's the information on how to do it:

1. Create a new option to the prompt question #5 concerning which template you'd like to deploy.
* The value for the template should be kept simple and easy.
2. Create a new directory under `/generator/templates`.
* 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`
3. The new template directory __must__ have a single first-level subdirectory named `src`.
4. Inside the `src` directory, you should add the following in an effort to give the template feature consistancy to the other templates:
* router.js
* main.js
* main.native.js (the NS-Vue project entry point)
* package.json (this is the standard NativeScript-Vue package.json file. Just copy/paste from the simple template)
* App.vue
* views/About.vue (optional)
* views/Home.vue (optional)
* components/HelloWorld.vue (optional)
* components/HelloWorld.native.vue (optional)
* components/HelloWorld.ios.vue (optional)
* components/HelloWorld.android.vue (optional)
* assets/logo.png (optional, but highly encouraged to prove images are loading)

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.

### Word of warning concerning using EJS templates with Prettier
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.

Loading