-
Notifications
You must be signed in to change notification settings - Fork 0
/
devto-articles.json
66 lines (66 loc) · 21.4 KB
/
devto-articles.json
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[
{
"type_of": "article",
"id": 281374,
"title": "Deploy to Github Pages like a pro with Github Actions",
"description": "Vue and React guide to deploy to Github Pages automating deployment with Github Actions",
"published": true,
"published_at": "2020-03-15T09:12:10.205Z",
"slug": "deploy-to-github-pages-like-a-pro-with-github-actions-4hdg",
"path": "/rolanddoda/deploy-to-github-pages-like-a-pro-with-github-actions-4hdg",
"url": "https://dev.to/rolanddoda/deploy-to-github-pages-like-a-pro-with-github-actions-4hdg",
"comments_count": 26,
"public_reactions_count": 192,
"page_views_count": 8529,
"published_timestamp": "2020-03-15T09:12:10Z",
"body_markdown": "---\ntitle: Deploy to Github Pages like a pro with Github Actions\npublished: true\ndescription: Vue and React guide to deploy to Github Pages automating deployment with Github Actions\ntags: #vue, #react, #git\n---\n\nGitHub Pages is a static site hosting service designed to host your personal, organization, or project pages directly from a GitHub repository.\n\nNote that GitHub Pages is a static site hosting service and doesn’t support server-side code such as, PHP, Ruby, or Python.\n\nTo learn more about the different types of GitHub Pages sites, take a look [here](https://help.github.com/articles/user-organization-and-project-pages/).\n\n🤨 That’s the theory! Let’s start: 🤨\n\n### **Copy the name of your project.**\n\n![](https://dev-to-uploads.s3.amazonaws.com/i/uegn7c6igtbri4igf7pf.png)\n\nThe name of my repo is `deploy-react-to-gh-pages`.\n\n### **For React specify the `homepage` in `package.json` [(Docs)](https://create-react-app.dev/docs/deployment/#building-for-relative-paths).**\n\n```json\n{\n ...\n \"homepage\": \"/name-of-your-project/\",\n ...\n}\n```\n\n![](https://dev-to-uploads.s3.amazonaws.com/i/uqdu3flrcyp836mw1n4e.png)\n\n\n\n### **For Vue create a new file in your project root named `vue.config.js` [(Docs)](https://cli.vuejs.org/config/#vue-config-js) and specify the `publicPath` [(Docs)](https://cli.vuejs.org/config/#publicpath).**\n\n```javascript\nmodule.exports = {\n publicPath: '/name-of-your-project/'\n}\n```\n\n\n\n### **Now commit and push your changes.**\n\n**Note: if you don't commit your changes, you will lose them in the next command, so make sure you don't skip this step**\n\n\n\n### **Open your terminal in your project and run:**\n\n**Note:** For the following commands, if you are using vue, just copy paste them, if you are using react replace `dist` with `build`.\n `npm run build` creates a directory with a production build of your app. In vue, that directory in named `dist`, in react is named `build`.\n\n- `git checkout --orphan gh-pages` [Docs](https://git-scm.com/docs/git-checkout/1.7.3.1#git-checkout---orphan)\n- `npm run build`\n- `git --work-tree dist add --all` [Docs](https://git-scm.com/docs/git#Documentation/git.txt---work-treeltpathgt) (**for react: replace dist with build**)\n- `git --work-tree dist commit -m 'Deploy'` (**for react: replace dist with build**)\n- `git push origin HEAD:gh-pages --force`\n- `rm -r dist` (**for react: replace dist with build**)\n- `git checkout -f master`\n- `git branch -D gh-pages`\n- Navigate to your github project and click 'Settings'\n ![](https://dev-to-uploads.s3.amazonaws.com/i/iup3jxzgr8f7v1gmjx33.png)\n- Scroll to find the section 'Github Pages' , select the `gh-pages` branch and click 'Save'\n ![](https://dev-to-uploads.s3.amazonaws.com/i/ttynt8nge4ajxb29txpn.png)\n\n### 🚀🚀 Congrats 🚀🚀\n\nYour site is ready to be published.\nYou might have to wait a bit. Generally it takes 2–10 minutes until this process is done.\n\n------\n\n\n🤔🤔But... wait. You probably want to re-deploy. There must be a simpler solution instead of re-doing over and over again all the commands above.\n\n### **Create a node.js script**\n\nNow, we are gonna create a node.js script so whenever we want to deploy, we just run one command.\n\n- Create a `scripts` folder in your project root.\n\n- Inside `scripts` folder, create a `gh-pages-deploy.js` file.\n\n- Copy and paste the code below:\n\n ```javascript\n const execa = require(\"execa\");\n const fs = require(\"fs\");\n \n (async () => {\n try {\n await execa(\"git\", [\"checkout\", \"--orphan\", \"gh-pages\"]);\n console.log(\"Building...\");\n await execa(\"npm\", [\"run\", \"build\"]);\n // Understand if it's dist or build folder\n const folderName = fs.existsSync(\"dist\") ? \"dist\" : \"build\";\n await execa(\"git\", [\"--work-tree\", folderName, \"add\", \"--all\"]);\n await execa(\"git\", [\"--work-tree\", folderName, \"commit\", \"-m\", \"gh-pages\"]);\n console.log(\"Pushing to gh-pages...\");\n await execa(\"git\", [\"push\", \"origin\", \"HEAD:gh-pages\", \"--force\"]);\n await execa(\"rm\", [\"-r\", folderName]);\n await execa(\"git\", [\"checkout\", \"-f\", \"master\"]);\n await execa(\"git\", [\"branch\", \"-D\", \"gh-pages\"]);\n console.log(\"Successfully deployed\");\n } catch (e) {\n console.log(e.message);\n process.exit(1);\n }\n })();\n ```\n\n- Open `package.json` and add `execa` ([Docs](https://www.npmjs.com/package/execa)) to your `devDependencies`.\n\n ```json\n \"devDependencies\": {\n ...\n \"execa\": \"latest\"\n },\n ```\n\n- Also add a new script in `scripts` section:\n\n ```json\n \"scripts\": {\n ...\n \"gh-pages-deploy\": \"node scripts/gh-pages-deploy.js\"\n },\n ```\n\n- Finally, run `npm install`.\n\n\n\n### ✨🎉 And... that's it! 🎉✨\n\n**You can now deploy as many times as you want by just running `npm run gh-pages-deploy`.**\n\n------\n\n**Me-** But, hey... 🤫🤫! Wouldn't be even more exciting if we automate everything ?\n\n**Everyone-** Do you mean that the app will be deployed itself ? 🤨🤨\n\n**Me-** 😉😉\n\n**Everyone-** 😲😲 \n\n**Github Pages-** 🤭🤭\n\n### Create a github action to automate deployment\n\nWouldn't be great if on every push on master, the app gets deployed without us doing nothing ?? 🧙♂️🧙♂️\n\nWe can achieve that by using... 🙌🙌 **Github Actions** 🙌🙌. \n\nGitHub Actions enables you to create custom software development life cycle (SDLC) workflows directly in your GitHub repository. [Docs](https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions)\n\nLet's start:\n\n- Create a `.github` (Don't forget the dot in front) folder in your project root\n\n- Inside create another folder named `workflows`\n\n- Inside `workflows` create a file named `gh-pages-deploy.yml` (The name is up to you).\n\n- Now copy & paste the code below inside that file.\n\n ```yaml\n name: Deploy to github pages\n on:\n push:\n branches:\n - master\n jobs:\n gh-pages-deploy:\n name: Deploying to gh-pages\n runs-on: ubuntu-latest\n steps:\n - name: Setup Node.js for use with actions\n uses: actions/[email protected]\n with:\n version: 12.x\n - name: Checkout branch\n uses: actions/checkout@v2\n \n - name: Clean install dependencies\n run: npm ci\n \n - name: Run deploy script\n run: |\n git config user.name \"Your username\" && git config user.email \"your email\"\n npm run gh-pages-deploy\n ```\n\n **Important:** Make sure to change your username and email:\n\n ![](https://dev-to-uploads.s3.amazonaws.com/i/z5j8iikvs1st8f10031x.png)\n\n \n\n- Commit and push your changes\n\n- Now, navigate to your github project and first click *Actions* (1) then *Deploy to github pages* (2) and last click on the action (3).\n\n ![](https://dev-to-uploads.s3.amazonaws.com/i/hrgn3ww1w75uxxdfuzen.png)\n\n- If everything goes well, you will see this:\n\n ![](https://dev-to-uploads.s3.amazonaws.com/i/2nshvsc10qivoif44d7f.png)\n\n\n\n### 🌟🌟 Taadaaa!!! You successfully automated deployment!!! 🌟🌟\n\n**Now, whenever you merge a PR or push to master this action will run and will deploy your app automatically**. 👏👏\n\n\n\n### Things to know\n\n- React & Vue provide their own steps to deploy on github pages:\n - For React, See the steps [Here](https://create-react-app.dev/docs/deployment/#github-pages).\n - For Vue, see the steps [Here](https://cli.vuejs.org/guide/deployment.html#github-pages).\n - Also [Read the steps to create a github action](https://help.github.com/en/actions/configuring-and-managing-workflows/configuring-a-workflow)\n- Great libraries to use for deploying to gh-pages:\n - [gh-pages](https://www.npmjs.com/package/gh-pages)\n - [push-dir](https://www.npmjs.com/package/push-dir)\n- It's definitely a good thing to know how to manually deploy to gh-pages. Also, the script is very minimal and easy to understand. This simplicity gives you the power to modify it. (add colors, emojis, promts).\n So here are some great resources to enrich the script:\n - [inquirer](https://www.npmjs.com/package/inquirer)\n - [ora](https://www.npmjs.com/package/ora)\n - [chalk](https://www.npmjs.com/package/chalk)\n - [node-emoji](https://www.npmjs.com/package/node-emoji)\n- Repositories (feel free to checkout the commits):\n - [deploy-vue-to-gh-pages](https://github.com/Rolanddoda/deploy-vue-to-gh-pages)\n - [deploy-react-to-gh-pages](https://github.com/Rolanddoda/deploy-react-to-gh-pages)\n\n🙏🙏 Thank you for reading. I would be glad to help you if you face any problem, so don't hesitate to email me at [email protected] 🙏🙏\n\n\n\n",
"positive_reactions_count": 192,
"cover_image": null,
"tag_list": [
"vue",
"react",
"git"
],
"canonical_url": "https://dev.to/rolanddoda/deploy-to-github-pages-like-a-pro-with-github-actions-4hdg",
"user": {
"name": "Roland Doda",
"username": "rolanddoda",
"twitter_username": "Roli_Dori",
"github_username": "Rolanddoda",
"website_url": null,
"profile_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--x7dZ_XEa--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/101292/844e638f-d0b0-4125-8207-b1a0205f062d.jpeg",
"profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--mo23YWvI--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/101292/844e638f-d0b0-4125-8207-b1a0205f062d.jpeg"
}
},
{
"type_of": "article",
"id": 140128,
"title": "8 secrets Vue Developers must know",
"description": "In this post I will explain 8 Vue tips ",
"published": true,
"published_at": "2019-07-13T19:17:25.045Z",
"slug": "8-secrets-vue-developers-must-know-5la",
"path": "/rolanddoda/8-secrets-vue-developers-must-know-5la",
"url": "https://dev.to/rolanddoda/8-secrets-vue-developers-must-know-5la",
"comments_count": 10,
"public_reactions_count": 175,
"page_views_count": 17924,
"published_timestamp": "2019-07-13T19:17:25Z",
"body_markdown": "---\ntitle: 8 secrets Vue Developers must know\npublished: true\ndescription: In this post I will explain 8 Vue tips \ntags: vue \n---\n\n- [Inline statement handler: Handle multiple arguments](#inline-statement-handler-handle-multiple-arguments)\n- [Emit event from functional components](#emit-event-from-functional-components)\n- [Pass all props to the child component](#pass-all-props-to-the-child-component)\n- [Watch child properties changes from parent](#watch-child-properties-changes-from-parent)\n- [Listening for child event in the router-view](#listening-for-child-event-in-the-router-view)\n- [Vue components lifecycle hooks don't run in the order you think they run](#vue-components-lifecycle-hooks-dont-run-in-the-order-you-think-they-run)\n- [How to know if a child component is mounted](#how-to-know-if-a-child-component-is-mounted-)\n- [How to know if a dynamically vuex registered module is registered](#how-to-know-if-a-dynamically-vuex-registered-module-is-registered-)\n\n------\n\n\n\n## **Inline statement handler: Handle multiple arguments** \n\n#### **Short Explanation:**\n\nIn an inline statement handler besides the `$event` special variable we have access to another special variable: **`arguments`**. `$event` will have access only to the first argument, whilst the `arguments` will have access to all arguments.\n\n#### **Detailed Explanation:**\n\nIn an inline statement handler we already know that we have access to the special `$event` variable.\n\nSo if a child components emits an event with a parameter, we have access to it by using `$event`:\n\n**Parent component**\n\n```html\n<template>\n // ...\n <Child @event=\"someVariable = $event\" />\n // ...\n</template>\n```\n\n**Child component**\n\n```js\nexport default {\n //...\n emitEvent () {\n this.$emit('event', 'a simple text')\n }\n //...\n}\n```\n\nThat works really well when the child component, is a component that we have access to, since we can be sure we pass only one parameter.\n\nBut how if we use a third-party component/library (e.g. dropzone.js) which passes many arguments up via event ?? \n\n**The `$event` will have access only to the first argument**. See this codesandbox example which illustrates that `$event` will catch only the first argument. (*Click the button and see the console*)\n\n{% codesandbox vue-event-special-variable-mj92o %}\n\n**In that case, instead of `$event` we can use `arguments` and all arguments will be accessible.**\n\nSo in the codesandbox above, in order to make it work, we have to change the line 4 in the `Child.vue`\n\n*from:*\n\n```html \n<GrandChild @event=\"$emit('event', $event)\"/> \n```\n\n*to:*\n\n```html\n <GrandChild @event=\"$emit('event', arguments)\"/>\n```\n\n------\n\n\n\n## **Emit event from functional components**\n\n#### **Short Explanation:**\n\nUsing functional components, means that we don't have access to `this` context. Thus, we cannot do `this.$emit()`. But... we have access to `listeners` so we can do `<button @click=\"listeners.clicked\"></button>`\n\n#### **Detailed Explanation:**\n\nFunctional components are stateless (no reactive data) and instanceless (no this context). But functional components have access to some properties such as `props`, `children` etc and most importantly (for this case), `listeners`.\n\nAccording to [Vue docs](https://vuejs.org/v2/guide/render-function.html#Functional-Components): \n**listeners: An object containing parent-registered event listeners. This is an alias to data.on**\n\nThat means that we can emit event from functional components. Wiii :P\n\n**Simple example:**\n\n```html\n<template functional>\n <button @click=\"listeners['custom-event']('message from child')\">\n Button from child\n </button>\n</template>\n```\n\n**Working example** (*click the button and open the console*)\n\n{% codesandbox pjvwo81py7 %}\n\nHow if we want to emit an event from functional component with render functions? Can we do that? Of course!\n\n**Simple example:**\n\n```js\nexport default {\n functional: true,\n render(createElement, { listeners }) {\n return createElement(\n \"button\",\n {\n on: {\n click: event => {\n const emit_event = listeners.event_from_child;\n emit_event(\"Hello World!Is this the message we excpected? :/\");\n }\n }\n },\n \"Pass event to parent\"\n );\n }\n};\n```\n\n**Working example**\n\n{% codesandbox k2nm1zxv8o %}\n\nSomeone may wonder if we can use [`.sync` Modifier](https://vuejs.org/v2/guide/components-custom-events.html#sync-Modifier) using this approach.\nThe answer ? Of course!\n\n```html\n<button @click=\"listeners['update:message']('some text')\">Click me</button>\n```\n\n------\n\n\n\n## **Pass all props to the child component**\n\nSay that we have a component which receives `props` and we want to pass all those props to a child component. To achieve that, we can do:\n\n```html\n <ChildComponent v-bind=\"$props\" />\n```\n\nTaking advantage of `v-bind` we can also have an object like:\n\n```js\ndata: () =>({\n obj: {\n firstName: 'John',\n lastName: 'Doe',\n age: 30\n }\n})\n```\n\nAnd pass `firstName`, `lastName`, `age` as `props` to a child component, like:\n\n\n```html\n<Child v-bind=\"obj\" />\n```\n\n------\n\n\n\n## **Watch child properties changes from parent**\n\nYou may wonder why to do that and you are right! That's a bad practice. But sometimes you use a third-party component and you want to watch their properties to fit your needs. \n\n*A long time ago, in a project we were using a date picker and we wanted to be able to detect when the popup was visible. Unfortunately there was no option to do that.I discovered that the date picker was using a `popupVisible` reactive property but it wasn't exposed by the library. So I had to somehow watch this property from my component.*\n\nThe below code is **NOT** able to detect changes:\n\n```js\n watch: {\n '$refs.datePicker.popupVisible': {\n handler (new_value) {\n console.log('value changed')\n },\n deep: true\n }\n }\n```\n\nIn order to detect changes of a child component's property you should do:\n\n```js\n mounted() {\n this.$watch(\n \"$refs.picker.popupVisible\",\n (new_value, old_value) => {\n //execute your code here\n }\n );\n }\n```\n\n**Working example:**\n\n{% codesandbox yk1l5zp9l9 %}\n\nLearn more about [`vm.$watch`](https://vuejs.org/v2/api/#vm-watch)\n\n------\n\n\n\n## **Listening for child event in the router view**\n\nMost of you, should already know that since it is straightforward, but I've been asked many times about the question below.\n\nSay you have a component which has nested routes:\n\n```html\n<template>\n //...\n <router-view></router-view>\n //...\n</template>\n```\n\nAnd you have a nested route as follow:\n\n\n```html\n<template>\n //...\n <button @click=\"$emit('event')\"></button>\n //...\n</template>\n```\n\nSo the component corresponding to a nested route, emits an event. The question is : **how to listen to that event ?**\n\nThe simple answer demonstrated with code:\n\n```html\n<template>\n //...\n <router-view @event=\"callAMethod\"></router-view>\n //...\n</template>\n```\n\n*Exactly! We listen to that event in the `router-view` component*\n\n------\n\n\n\n## **Vue components lifecycle hooks don't run in the order you think they run**\n\nSay you have 2 pages. Home and About.\n\nWhen switching from Home to About, **the `created` hook of the About component will run before the `beforeDestroy` hook of Home component.** (*take a moment here*)\n\nWeird?? Try switching routes in the working example below by seeing the console.\n\n{% codesandbox vue-lifecycle-hooks-not-running-in-the-way-you-expect-e4y31 %}\n\nAs solution (idk if it's the best solution though) you can use [transition-mode](https://vuejs.org/v2/guide/transitions.html#Transition-Modes) **out-in**\n\n```html\n <transition mode=\"out-in\">\n <router-view></router-view>\n </transition>\n```\n\n------\n\n\n\n## **How to know if a child component is mounted ?**\n\nThis one of my favorite tips I've read [here (Vue Dose)](https://vuedose.tips/tips/listen-to-lifecycle-hooks-on-third-party-vue-js-components)\n\nSay you have a child component and you want to do something when a hook of the child component is executed. You can do:\n\n```html\n<Child @hook:created=\"doSomething\" />\n```\n\nSo the question to *How to know when a child component mounted* is:\n\n```html\n<Child @hook:mounted=\"componentMountedDoSomething\" />\n```\n\n------\n\n\n\n## **How to know if a dynamically vuex registered module is registered ?**\n\nWith the power of dynamically [register/unregister](https://vuex.vuejs.org/guide/modules.html#dynamic-module-registration) vuex modules we can improve the performance a lot.\n\n*I recommend you to read a very useful article: [Performance optimization: Lazy load vuex modules](https://itnext.io/vue-js-app-performance-optimization-part-3-lazy-loading-vuex-modules-ed67cf555976)*\n\nWe can register a vuex module:\n\n`this.$store.registerModule('my-module', MyModule)`\n\nAnd unregister it:\n\n`this.$store.unregisterModule('my-module')`\n\nTo know if a module is already registered:\n\n```js\nif (Object.keys(this.$store._modules.root._children).includes('my-module')) {\n // module is registered\n}\n```\n\n> My time is very limited but I am glad that I found some time to write this article (it took me some time though). I hope it helped and you enjoyed reading it.\n\n\n*I would be very happy if you leave a comment providing your solution. For example regarding the last \"secret\" you can use vuex store to indicate that a module is registered or not.*\n\n> This is my first article on *DEV community*. Thank you for reading.",
"positive_reactions_count": 175,
"cover_image": null,
"tag_list": [
"vue"
],
"canonical_url": "https://dev.to/rolanddoda/8-secrets-vue-developers-must-know-5la",
"user": {
"name": "Roland Doda",
"username": "rolanddoda",
"twitter_username": "Roli_Dori",
"github_username": "Rolanddoda",
"website_url": null,
"profile_image": "https://res.cloudinary.com/practicaldev/image/fetch/s--x7dZ_XEa--/c_fill,f_auto,fl_progressive,h_640,q_auto,w_640/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/101292/844e638f-d0b0-4125-8207-b1a0205f062d.jpeg",
"profile_image_90": "https://res.cloudinary.com/practicaldev/image/fetch/s--mo23YWvI--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/101292/844e638f-d0b0-4125-8207-b1a0205f062d.jpeg"
}
}
]