Skip to content

Commit 5c6e98b

Browse files
authored
Add in debugging recipe, delete unused categories from cookbook TOC (#1464)
* add in debugging recipe, delete unused categories from cookbook TOC * VSCode => VS Code * update PR based on review- title edits, clarification of sourcemaps, point to readmes
1 parent 80d60d3 commit 5c6e98b

File tree

7 files changed

+152
-29
lines changed

7 files changed

+152
-29
lines changed

src/images/breakpoint_hit.png

610 KB
Loading

src/images/breakpoint_set.png

536 KB
Loading

src/images/config_add.png

518 KB
Loading

src/images/devtools-timetravel.gif

313 KB
Loading

src/images/vuetron-heirarchy.gif

3.37 MB
Loading

src/v2/cookbook/adding-instance-properties.md

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ order: 2
88

99
There may be data/utilities you'd like to use in many components, but you don't want to [pollute the global scope](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md). In these cases, you can make them available to each Vue instance by defining them on the prototype:
1010

11-
``` js
11+
```js
1212
Vue.prototype.$appName = 'My App'
1313
```
1414

1515
Now `$appName` is available on all Vue instances, even before creation. If we run:
1616

17-
``` js
17+
```js
1818
new Vue({
19-
beforeCreate: function () {
19+
beforeCreate: function() {
2020
console.log(this.$appName)
2121
}
2222
})
@@ -36,23 +36,23 @@ No magic is happening here. `$` is a convention Vue uses for properties that are
3636
3737
Another great question! If you set:
3838

39-
``` js
39+
```js
4040
Vue.prototype.appName = 'My App'
4141
```
4242

4343
Then what would you expect to be logged below?
4444

45-
``` js
45+
```js
4646
new Vue({
4747
data: {
4848
// Uh oh - appName is *also* the name of the
4949
// instance property we defined!
5050
appName: 'The name of some other app'
5151
},
52-
beforeCreate: function () {
52+
beforeCreate: function() {
5353
console.log(this.appName)
5454
},
55-
created: function () {
55+
created: function() {
5656
console.log(this.appName)
5757
}
5858
})
@@ -66,7 +66,7 @@ Let's say you're replacing the [now-retired Vue Resource](https://medium.com/the
6666

6767
All you have to do is include axios in your project:
6868

69-
``` html
69+
```html
7070
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.2/axios.js"></script>
7171

7272
<div id="app">
@@ -78,22 +78,23 @@ All you have to do is include axios in your project:
7878

7979
Alias `axios` to `Vue.prototype.$http`:
8080

81-
``` js
81+
```js
8282
Vue.prototype.$http = axios
8383
```
8484

8585
Then you'll be able to use methods like `this.$http.get` in any Vue instance:
8686

87-
``` js
87+
```js
8888
new Vue({
8989
el: '#app',
9090
data: {
9191
users: []
9292
},
93-
created () {
93+
created() {
9494
var vm = this
95-
this.$http.get('https://jsonplaceholder.typicode.com/users')
96-
.then(function (response) {
95+
this.$http
96+
.get('https://jsonplaceholder.typicode.com/users')
97+
.then(function(response) {
9798
vm.users = response.data
9899
})
99100
}
@@ -106,34 +107,40 @@ In case you're not aware, methods added to a prototype in JavaScript gain the co
106107

107108
Let's take advantage of this in a `$reverseText` method:
108109

109-
``` js
110-
Vue.prototype.$reverseText = function (propertyName) {
111-
this[propertyName] = this[propertyName].split('').reverse().join('')
110+
```js
111+
Vue.prototype.$reverseText = function(propertyName) {
112+
this[propertyName] = this[propertyName]
113+
.split('')
114+
.reverse()
115+
.join('')
112116
}
113117

114118
new Vue({
115119
data: {
116120
message: 'Hello'
117121
},
118-
created: function () {
119-
console.log(this.message) // => "Hello"
122+
created: function() {
123+
console.log(this.message) // => "Hello"
120124
this.$reverseText('message')
121-
console.log(this.message) // => "olleH"
125+
console.log(this.message) // => "olleH"
122126
}
123127
})
124128
```
125129

126-
Note that the context binding will __not__ work if you use an ES6/2015 arrow function, as they implicitly bind to their parent scope. That means the arrow function version:
130+
Note that the context binding will **not** work if you use an ES6/2015 arrow function, as they implicitly bind to their parent scope. That means the arrow function version:
127131

128-
``` js
132+
```js
129133
Vue.prototype.$reverseText = propertyName => {
130-
this[propertyName] = this[propertyName].split('').reverse().join('')
134+
this[propertyName] = this[propertyName]
135+
.split('')
136+
.reverse()
137+
.join('')
131138
}
132139
```
133140

134141
Would throw an error:
135142

136-
``` log
143+
```log
137144
Uncaught TypeError: Cannot read property 'split' of undefined
138145
```
139146

@@ -143,27 +150,30 @@ As long as you're vigilant in scoping prototype properties, using this pattern i
143150

144151
However, it can sometimes cause confusion with other developers. They might see `this.$http`, for example, and think, "Oh, I didn't know about this Vue feature!" Then they move to a different project and are confused when `this.$http` is undefined. Or, maybe they want to Google how to do something, but can't find results because they don't realize they're actually using Axios under an alias.
145152

146-
__The convenience comes at the cost of explicitness.__ When looking at a component, it's impossible to tell where `$http` came from. Vue itself? A plugin? A coworker?
153+
**The convenience comes at the cost of explicitness.** When looking at a component, it's impossible to tell where `$http` came from. Vue itself? A plugin? A coworker?
147154

148155
So what are the alternatives?
149156

150157
## Alternative Patterns
151158

152159
### When Not Using a Module System
153160

154-
In applications with __no__ module system (e.g. via Webpack or Browserify), there's a pattern that's often used with _any_ JavaScript-enhanced frontend: a global `App` object.
161+
In applications with **no** module system (e.g. via Webpack or Browserify), there's a pattern that's often used with _any_ JavaScript-enhanced frontend: a global `App` object.
155162

156163
If what you want to add has nothing to do with Vue specifically, this may be a good alternative to reach for. Here's an example:
157164

158-
``` js
165+
```js
159166
var App = Object.freeze({
160167
name: 'My App',
161168
description: '2.1.4',
162169
helpers: {
163170
// This is a purely functional version of
164171
// the $reverseText method we saw earlier
165-
reverseText: function (text) {
166-
return text.split('').reverse().join('')
172+
reverseText: function(text) {
173+
return text
174+
.split('')
175+
.reverse()
176+
.join('')
167177
}
168178
}
169179
})
@@ -175,7 +185,7 @@ Now the source of these shared properties is more obvious: there's an `App` obje
175185

176186
Another advantage is that `App` can now be used _anywhere_ in your code, whether it's Vue-related or not. That includes attaching values directly to instance options, rather than having to enter a function to access properties on `this`:
177187

178-
``` js
188+
```js
179189
new Vue({
180190
data: {
181191
appVersion: App.version
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
title: Debugging in VS Code and Chrome
3+
type: cookbook
4+
order: 8
5+
---
6+
7+
Every application reaches a point where it's necessary to understand failures, small to large. In this recipe, we explore a few workflows for VS Code users, who are using Chrome to test.
8+
9+
This recipe shows how to use the [Debugger for Chrome](https://github.com/Microsoft/VSCode-chrome-debug) extension with VS Code to debug Vue.js applications generated by the [Vue CLI](https://github.com/vuejs/vue-cli).
10+
11+
## Prerequisites
12+
13+
You must have Chrome and VS Code installed. Make sure to get the latest version of [Debugger for Chrome](https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome) extension installed in VS Code.
14+
15+
Install and create a project with the [vue-cli](https://github.com/vuejs/vue-cli), with the instructions for installation documented in the readme of the project. Change into the newly created application directory and open VS Code.
16+
17+
### Showing Source Code in the Chrome Devtools
18+
19+
Before you can debug your Vue components from VS Code you need to update the generated Webpack config to build sourcemaps. We do this so that our debugger has a way to map the code within a compressed file back to its position in the original file. This ensures that you can debug an application even after your assets have been optimized by Webpack.
20+
21+
Go to `config/index.js` and find the `devtool` property. Update it to:
22+
23+
```json
24+
devtool: 'source-map',
25+
```
26+
27+
### Launching the Application from VS Code
28+
29+
Click on the Debugging icon in the Activity Bar to bring up the Debug view, then click on the gear icon to configure a launch.json file, selecting **Chrome** for the environment. Replace content of the generated launch.json with the following two configurations:
30+
31+
![Add Chrome Configuration](/images/config_add.png)
32+
33+
```json
34+
{
35+
"version": "0.2.0",
36+
"configurations": [
37+
{
38+
"type": "chrome",
39+
"request": "launch",
40+
"name": "vuejs: chrome",
41+
"url": "http://localhost:8080",
42+
"webRoot": "${workspaceFolder}/src",
43+
"breakOnLoad": true,
44+
"sourceMapPathOverrides": {
45+
"webpack:///src/*": "${webRoot}/*"
46+
}
47+
}
48+
]
49+
}
50+
```
51+
52+
## Setting a Breakpoint
53+
54+
1. Set a breakpoint in **src/components/HelloWorld.vue** on `line 90` where the `data` function returns a string.
55+
56+
![Breakpoint Renderer](/images/breakpoint_set.png)
57+
58+
2. Open your favorite terminal at the root folder and serve the app using Vue CLI:
59+
60+
```
61+
npm start
62+
```
63+
64+
3. Go to the Debug view, select the **'vuejs: chrome'** configuration, then press F5 or click the green play button.
65+
66+
4. Your breakpoint should now be hit as the new instance of Chrome opens `http://localhost:8080`.
67+
68+
![Breakpoint Hit](/images/breakpoint_hit.png)
69+
70+
## Alternative Patterns
71+
72+
### Vue Devtools
73+
74+
There are other methods of debugging, varying in complexity. The most popular and simple of which is to use the excellent [vue-devtools](https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd). Some of the benefits of working with the devtools are that they enable you to live-edit data properties and see the changes reflected immediately. The other major benefit is the ability to do time travel debugging for Vuex.
75+
76+
![Devtools Timetravel Debugger](/images/devtools-timetravel.gif)
77+
78+
<p class="tip">Please note that if the page uses a production/minified build of Vue.js (such as the standard link from a CDN), devtools inspection is disabled by default so the Vue pane won't show up. If you switch to an unminified version, you may have to give the page a hard refresh to see them.</p>
79+
80+
### Vuetron
81+
82+
[Vuetron](http://vuetron.io/) is a really nice project that extends some of the work that vue-devtools has done. In addition to the normal devtools workflow, you are able to:
83+
84+
* Quickly view API Request/Response: if you're using the fetch API for requests, this event is displayed for any request sent. The expanded card displays the request data as well as the response data.
85+
* Subscribe to specific parts of your application’s state for faster debugging
86+
* Visualize component hierarchy, and an animation allows you to collapse or expand the tree for specific hierarchy views.
87+
88+
![Vuetron Heirarchy](/images/vuetron-heirarchy.gif)
89+
90+
### Simple Debugger Statement
91+
92+
The example above has a great workflow. However, there is an alternative option where you can use the [native debugger statement](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger) directly in your code. If you choose to work this way, it's important that you remember to remove the statements when you're done.
93+
94+
```js
95+
<script>
96+
export default {
97+
data() {
98+
return {
99+
message: ''
100+
}
101+
},
102+
mounted() {
103+
const hello = 'Hello World!'
104+
debugger
105+
this.message = hello
106+
}
107+
};
108+
</script>
109+
```
110+
111+
## Acknowledgements
112+
113+
This recipe was based on a contribution from [Kenneth Auchenberg](https://twitter.com/auchenberg), [available here](https://github.com/Microsoft/VSCode-recipes/tree/master/vuejs-cli).

0 commit comments

Comments
 (0)