<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yw Zhang</title>
    <description>The latest articles on DEV Community by Yw Zhang (@zhng1456).</description>
    <link>https://dev.to/zhng1456</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F913894%2Fbb12b13f-3bc9-4256-bb69-2c3ae25cb65a.jpeg</url>
      <title>DEV Community: Yw Zhang</title>
      <link>https://dev.to/zhng1456</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhng1456"/>
    <language>en</language>
    <item>
      <title>Easy Way to Integrate Algolia to VuePress Application</title>
      <dc:creator>Yw Zhang</dc:creator>
      <pubDate>Sun, 30 Oct 2022 14:16:00 +0000</pubDate>
      <link>https://dev.to/zhng1456/easy-way-to-integrate-algolia-to-vuepress-application-22ao</link>
      <guid>https://dev.to/zhng1456/easy-way-to-integrate-algolia-to-vuepress-application-22ao</guid>
      <description>&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;The search that comes with VuePress, although it can be used out of the box, does not support more complex search scenarios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Algolia
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.algolia.com/"&gt;Algolia&lt;/a&gt; empowers Builders with Search and Recommendation services to create world-class digital experiences.&lt;strong&gt;I chose the free service.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IvEEZA2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzdfv98x1jdh4id1lvba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IvEEZA2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzdfv98x1jdh4id1lvba.png" alt="Image description" width="880" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Register and Create Index
&lt;/h3&gt;

&lt;p&gt;First, register with Algolia. Then you need to upload the document information in VuePress application to Algolia. &lt;a href="https://docsearch.algolia.com/"&gt;DocSearch&lt;/a&gt; provides a crawler and UI to easily crawl index information and upload it. However, you need to meet certain &lt;a href="https://docsearch.algolia.com/docs/who-can-apply"&gt;conditions&lt;/a&gt; to apply for this service. Fortunately, the old version of DocSearch provided a solution to run the crawler yourself. So I ended up with the &lt;a href="https://docsearch.algolia.com/docs/legacy/run-your-own/"&gt;Run Your Own&lt;/a&gt; solution.&lt;/p&gt;

&lt;p&gt;create a .env file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;APPLICATION_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_APP_ID
&lt;span class="nv"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;YOUR_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;install jq&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create config.json file that describes the crawler rules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "index_name": "xxxxxx",
  "start_urls": ["www.example.com"],
  "selectors": {
    "lvl0": ".theme-default-content h1",
    "lvl1": ".theme-default-content h2",
    "lvl2": ".theme-default-content h3",
    "lvl3": ".theme-default-content h4",
    "lvl4": ".theme-default-content h5",
    "lvl5": ".theme-default-content h6",
    "text": ".theme-default-content p, .theme-default-content li",
        "lang": {
      "selector": "/html/@lang",
      "type": "xpath",
      "global": true
    }
  },
    "custom_settings": {
    "attributesForFaceting": [
      "lang"
    ]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the crawler&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--env-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.env &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"CONFIG=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; /path/to/your/config.json | jq &lt;span class="nt"&gt;-r&lt;/span&gt; tostring&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; algolia/docsearch-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm your index in Algolia console.&lt;/p&gt;

&lt;h2&gt;
  
  
  VuePress Config
&lt;/h2&gt;

&lt;p&gt;I use the default theme so my config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;themeConfig: &lt;span class="o"&gt;{&lt;/span&gt;
    nav: navConfig,
    smoothScroll: &lt;span class="nb"&gt;true&lt;/span&gt;,
    algolia: &lt;span class="o"&gt;{&lt;/span&gt;
      apiKey: &lt;span class="s1"&gt;'&amp;lt;API_KEY&amp;gt;'&lt;/span&gt;,
      indexName: &lt;span class="s1"&gt;'&amp;lt;INDEX_NAME&amp;gt;'&lt;/span&gt;,
      appId: &lt;span class="s1"&gt;'&amp;lt;APP_ID&amp;gt;'&lt;/span&gt;,
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the application and search !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W6HQJBjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9gwja51tyqrw838kw257.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W6HQJBjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9gwja51tyqrw838kw257.png" alt="Image description" width="880" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Points
&lt;/h2&gt;

&lt;p&gt;Looking at the HTTP request parameters, we can see “Facefilters”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TiuH5wBg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrk0lx1kovnr53d6kine.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TiuH5wBg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wrk0lx1kovnr53d6kine.png" alt="Image description" width="764" height="204"&gt;&lt;/a&gt;&lt;br&gt;
This parameter is default and there is a &lt;a href="https://github.com/vuejs/vuepress/issues/2802"&gt;issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you don't want to modify frontend components, the index must have the lang attribute.&lt;/strong&gt;This is why there are lang configurations in the crawler rules.&lt;/p&gt;

&lt;p&gt;In addition, your crawler rules need to be consistent with your page.I use default theme and html code is like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"theme-default-content content__default"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&amp;lt;h1 &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"jian-jie"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;a &lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#jian-jie"&lt;/span&gt; &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"header-anchor"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;#&amp;lt;/a&amp;gt; Introduction&amp;lt;/h1&amp;gt; &lt;/span&gt;
&amp;lt;p&amp;gt;xxxxxxxxxxxxxx&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use other vuepress themes, you can customize your crawler rules.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Create Your Own Vue Application: Authentication with Firebase</title>
      <dc:creator>Yw Zhang</dc:creator>
      <pubDate>Thu, 06 Oct 2022 02:41:29 +0000</pubDate>
      <link>https://dev.to/zhng1456/create-your-own-vue-application-authentication-with-firebase-39lf</link>
      <guid>https://dev.to/zhng1456/create-your-own-vue-application-authentication-with-firebase-39lf</guid>
      <description>&lt;p&gt;As  a programmer,everyone wants to create magic app.The first step is to authenticate users to your application.Firebase authentication provides backend services to help authenticate users to your application. To integrate Firebase authentication to your application, you can use either the &lt;a href="https://firebase.google.com/docs/auth/android/firebaseui" rel="noopener noreferrer"&gt;Firebase UI&lt;/a&gt; which handles the UI flows for signing in users using different providers or you can manually set up the Firebase SDK in your project and provide support for any provider you would like to use.&lt;/p&gt;

&lt;p&gt;In this tutorial,We’ll integrate Firebase UI to a Vue,Vue router project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up a Firebase Project
&lt;/h2&gt;

&lt;p&gt;Sign in  &lt;a href="https://firebase.google.com/" rel="noopener noreferrer"&gt;https://firebase.google.com/&lt;/a&gt; and create a new project.Under the authentication tab for your project, click the sign-in method and you should see a list of providers Firebase currently supports.Next,enable Email/Password and Github.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxxxtl90imv3kfx39med.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flxxxtl90imv3kfx39med.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue Project
&lt;/h2&gt;

&lt;p&gt;Create the project and choose Vue2.x,Vue Router,Vuex.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vue create firbase-auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next,install the dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;firbase-auth
npm &lt;span class="nb"&gt;install &lt;/span&gt;firebase
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Firebase Config
&lt;/h2&gt;

&lt;p&gt;Init firebase SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import firebase from &lt;span class="s1"&gt;'firebase/compat/app'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import Cookies from &lt;span class="s2"&gt;"js-cookie"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const config &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
// get your project config from firebase console
&lt;span class="o"&gt;}&lt;/span&gt;

firebase.initializeApp&lt;span class="o"&gt;(&lt;/span&gt;config&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

firebase.auth&lt;span class="o"&gt;()&lt;/span&gt;.onAuthStateChanged&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;user&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;user&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    user.getIdToken&lt;span class="o"&gt;()&lt;/span&gt;.then&lt;span class="o"&gt;(&lt;/span&gt;idToken &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Cookies.set&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'access-token'&lt;/span&gt;, idToken, &lt;span class="o"&gt;{&lt;/span&gt; expires: 2 &lt;span class="o"&gt;}))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;, &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;const firebaseAuth &lt;span class="o"&gt;=&lt;/span&gt; firebase.auth&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new Component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;template&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;div &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'firebaseui-auth-container'&lt;/span&gt; v-if&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'!isLogin'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div v-else&amp;gt;
      &amp;lt;span&amp;gt;You already logged &lt;span class="k"&gt;in&lt;/span&gt;&amp;lt;/span&amp;gt;
      &amp;lt;button @click&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'handleSignOut'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;SignOut&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import firebase from &lt;span class="s1"&gt;'firebase/compat/app'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="s1"&gt;'firebase/compat/auth'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="s1"&gt;'firebase/compat/firestore'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="k"&gt;*&lt;/span&gt; as firebaseui from &lt;span class="s1"&gt;'firebaseui'&lt;/span&gt;
import &lt;span class="s1"&gt;'firebaseui/dist/firebaseui.css'&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; firebaseAuth &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"@/conf/firebaseConfig"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; Common &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s2"&gt;"@/utils"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import Cookies from &lt;span class="s2"&gt;"js-cookie"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="o"&gt;{&lt;/span&gt;
  data&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      isLogin: Common.validString&lt;span class="o"&gt;(&lt;/span&gt;Cookies.get&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'access-token'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  mounted&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;Common.validString&lt;span class="o"&gt;(&lt;/span&gt;Cookies.get&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'access-token'&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    const firebaseConfigUI &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      signInSuccessUrl: &lt;span class="s1"&gt;'http://localhost:8080'&lt;/span&gt;,
      signInOptions: &lt;span class="o"&gt;[&lt;/span&gt;
        firebaseAuth.GithubAuthProvider.PROVIDER_ID,
        firebaseAuth.EmailAuthProvider.PROVIDER_ID,
      &lt;span class="o"&gt;]&lt;/span&gt;,
      tosUrl: &lt;span class="s1"&gt;'&amp;lt;your-tos-url&amp;gt;'&lt;/span&gt;,
      // Privacy policy url/callback.
      privacyPolicyUrl: &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        window.location.assign&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'&amp;lt;your-privacy-policy-url&amp;gt;'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    const ui &lt;span class="o"&gt;=&lt;/span&gt; firebaseui.auth.AuthUI.getInstance&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; new firebaseui.auth.AuthUI&lt;span class="o"&gt;(&lt;/span&gt;firebase.auth&lt;span class="o"&gt;())&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    ui.start&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'#firebaseui-auth-container'&lt;/span&gt;, firebaseConfigUI&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  methods: &lt;span class="o"&gt;{&lt;/span&gt;
    handleSignOut&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      firebaseAuth&lt;span class="o"&gt;()&lt;/span&gt;.signOut&lt;span class="o"&gt;()&lt;/span&gt;.then&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'signOut success'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        Cookies.remove&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'access-token'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        Cookies.remove&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'urlBeforeSso'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        window.location.reload&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;})&lt;/span&gt;.catch&lt;span class="o"&gt;((&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        console.log&lt;span class="o"&gt;(&lt;/span&gt;error&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&amp;lt;/script&amp;gt;

&amp;lt;style scoped&amp;gt;

&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Config the router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import Vue from &lt;span class="s1"&gt;'vue'&lt;/span&gt;
import VueRouter from &lt;span class="s1"&gt;'vue-router'&lt;/span&gt;
import HomeView from &lt;span class="s1"&gt;'../views/HomeView.vue'&lt;/span&gt;
import AboutView from &lt;span class="s1"&gt;'../views/AboutView'&lt;/span&gt;
import FirebaseUiLogIn from &lt;span class="s2"&gt;"@/components/FirebaseUILogIn"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

Vue.use&lt;span class="o"&gt;(&lt;/span&gt;VueRouter&lt;span class="o"&gt;)&lt;/span&gt;

const routes &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
  &lt;span class="o"&gt;{&lt;/span&gt; path: &lt;span class="s1"&gt;'/'&lt;/span&gt;, name: &lt;span class="s1"&gt;'home'&lt;/span&gt;, component: HomeView &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt; path: &lt;span class="s1"&gt;'/about'&lt;/span&gt;, name: &lt;span class="s1"&gt;'about'&lt;/span&gt;, component: AboutView &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="o"&gt;{&lt;/span&gt; path: &lt;span class="s1"&gt;'/signIn'&lt;/span&gt;, name: &lt;span class="s1"&gt;'signIn'&lt;/span&gt;, component: FirebaseUiLogIn &lt;span class="o"&gt;}&lt;/span&gt;,
&lt;span class="o"&gt;]&lt;/span&gt;

const router &lt;span class="o"&gt;=&lt;/span&gt; new VueRouter&lt;span class="o"&gt;({&lt;/span&gt;
  routes
&lt;span class="o"&gt;})&lt;/span&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;default router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Advanced usage&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now I want every one can access home page, the page “/about” are only open for logged users.&lt;a href="https://ricostacruz.com/nprogress/" rel="noopener noreferrer"&gt;Nprogress&lt;/a&gt; is a nanoscopic progress bar and I import the dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import Cookies from &lt;span class="s1"&gt;'js-cookie'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="o"&gt;{&lt;/span&gt; req, Common &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'@/utils'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import router from &lt;span class="s1"&gt;'@/router'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import NProgress from &lt;span class="s1"&gt;'nprogress'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
import &lt;span class="s1"&gt;'nprogress/nprogress.css'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

NProgress.configure&lt;span class="o"&gt;({&lt;/span&gt; showSpinner: &lt;span class="nb"&gt;false&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

const isLogin &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Common.validString&lt;span class="o"&gt;(&lt;/span&gt;Cookies.get&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'access-token'&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

router.beforeEach&lt;span class="o"&gt;((&lt;/span&gt;to, from, next&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  NProgress.start&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;to.path &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'/signin'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;isLogin&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      next&lt;span class="o"&gt;({&lt;/span&gt; path: &lt;span class="s1"&gt;'/'&lt;/span&gt; &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      NProgress.done&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      next&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;to.path &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'/404'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; to.path &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; isLogin&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    next&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;isLogin&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    next&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    req.redirectToSso&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    Cookies.set&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'urlBeforeSso'&lt;/span&gt;, to.fullPath&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    next&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    NProgress.done&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

router.afterEach&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  NProgress.done&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is the code of "req.redirectToSso"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Cookies from 'js-cookie';
import axios from 'axios';
import { Notification } from 'element-ui';
import Common from "@/utils/common";

const req = {};

req.redirectToSso = () =&amp;gt; {
    if (window.location.href.indexOf('#/signin') &amp;gt; -1) {
        return;
    }
    Cookies.set('urlBeforeSso', window.location.href);
    window.location.href = window.location.origin + window.location.pathname + '#/signin';
};

export default req;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then import permission.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import Vue from &lt;span class="s1"&gt;'vue'&lt;/span&gt;
import App from &lt;span class="s1"&gt;'./App.vue'&lt;/span&gt;
import router from &lt;span class="s1"&gt;'./router'&lt;/span&gt;
import store from &lt;span class="s1"&gt;'./store'&lt;/span&gt;
import ElementUI from &lt;span class="s1"&gt;'element-ui'&lt;/span&gt;
import &lt;span class="s1"&gt;'./permission'&lt;/span&gt;

Vue.use&lt;span class="o"&gt;(&lt;/span&gt;ElementUI&lt;span class="o"&gt;)&lt;/span&gt;
Vue.config.productionTip &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false

&lt;/span&gt;new Vue&lt;span class="o"&gt;({&lt;/span&gt;
  router,
  store,
  render: h &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; h&lt;span class="o"&gt;(&lt;/span&gt;App&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;.&lt;span class="nv"&gt;$mount&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'#app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6eso43aqfrdy1thorv3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6eso43aqfrdy1thorv3x.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click about page and url redirects to "/signin".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3lwdkafay9ulemepkhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg3lwdkafay9ulemepkhp.png" alt="Image description"&gt;&lt;/a&gt;&lt;br&gt;
I choose "signIn with Github".After a successful login, I am able to access the about page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8k0udamtvlvijm0p61m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8k0udamtvlvijm0p61m.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About me
&lt;/h2&gt;

&lt;p&gt;I'm a programmer dedicated to sharing code and knowledge.Currently I'm working on the development of a recommender system, and I'm preparing to build a recommender system using firebase's related functions. So, in this post I try to write the login module.You can find the complete code in github &lt;a href="https://github.com/zhng1456/recommend-system" rel="noopener noreferrer"&gt;recommend-system&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My next plan is to code the backend of the recommender system. The interaction between the backend and the frontend can refer to &lt;a href="https://dev.to/zhng1456/easy-way-to-separate-java-backend-and-vue-frontend-3f5n"&gt;my previous article&lt;/a&gt;. Finally, thanks for reading.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/zhng1456" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.buymeacoffee.com%2Fbuttons%2Fv2%2Fdefault-yellow.png" alt="Buy Me A Coffee"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>firebase</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Deploy Vue Frontend</title>
      <dc:creator>Yw Zhang</dc:creator>
      <pubDate>Tue, 20 Sep 2022 13:26:33 +0000</pubDate>
      <link>https://dev.to/zhng1456/how-to-deploy-vue-frontend-17ph</link>
      <guid>https://dev.to/zhng1456/how-to-deploy-vue-frontend-17ph</guid>
      <description>&lt;p&gt;This is the part of &lt;a href="https://dev.to/zhng1456/easy-way-to-separate-java-backend-and-vue-frontend-3f5n"&gt;Easy Way to Separate Java Backend and Vue Frontend&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Google Cloud Storage Client
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @google-cloud/storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Google Cloud Storage Authentication
&lt;/h2&gt;

&lt;p&gt;(1)Open IAM &amp;amp; Admin of Google cloud console&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bbmCjd0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wbc8rp9r5tkomuq3uxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bbmCjd0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wbc8rp9r5tkomuq3uxx.png" alt="IAM &amp;amp; Admin" width="550" height="1004"&gt;&lt;/a&gt;&lt;br&gt;
(2)Click &lt;strong&gt;Service Accounts&lt;/strong&gt; and create services account&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--emIyyxLZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9yrck2fgebepazpkccq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--emIyyxLZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9yrck2fgebepazpkccq.png" alt="Image description" width="438" height="80"&gt;&lt;/a&gt;&lt;br&gt;
Choose the role&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eIt77zxm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7wg6guawuuj44suzpkt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eIt77zxm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7wg6guawuuj44suzpkt.png" alt="Image description" width="880" height="650"&gt;&lt;/a&gt;&lt;br&gt;
(3)Manage keys of new account&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DJmb6U6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7g775vh8z2z30zjw297.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DJmb6U6Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r7g775vh8z2z30zjw297.png" alt="Image description" width="380" height="496"&gt;&lt;/a&gt;&lt;br&gt;
(4)Create new key and browser will download the json key.&lt;br&gt;
I name the key file "google-secret.json".&lt;br&gt;
Remember add the key file to .gitignore&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target
.DS_Store
.idea
*.iml
athena.js
athena.css
admin.js
admin.css

.vscode/*
.factorypath
.project
.classpath
*.prefs

node_modules
package-lock.json
dist

google-secret.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Write Script
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const {Storage} = require('@google-cloud/storage');

const fileName = 'app';
const bucketName = 'webpack-frontend';
const storage = new Storage({
  keyFilename: './google-secret.json',
  projectId: 'crested-polygon-362000'
});
const projectBucket = storage.bucket(bucketName);

const uploadFiles = target =&amp;gt; {
  return projectBucket.upload(`./dist/static/${target}`);
};

const deploy = (fn, arr = []) =&amp;gt; {
  if (arr.length === 0) {
    return;
  }
  let ele = arr.shift();
  fn(ele).then(data =&amp;gt; {
    console.log(data);
    deploy(fn, arr);
  }).catch(console.log);
};

deploy(uploadFiles, [`js/${fileName}.js`, `css/${fileName}.css`])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script uploads dist/static/js/app.js and dist/static/css/css.js to Google Cloud Storage.&lt;br&gt;
Run the following command to run the script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node deploy.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm the logs.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--msyv8Vjp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/woslw9aiuw23zg9h1kgc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--msyv8Vjp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/woslw9aiuw23zg9h1kgc.png" alt="Image description" width="880" height="482"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Config npm Command
&lt;/h2&gt;

&lt;p&gt;Config the deploy script in package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "lint": "eslint --ext .js,.vue src",
    "build": "node build/build.js",
    "deploy": "node deploy.js"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can easily deploy vue project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
npm run deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>vue</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Easy Way to Separate Java Backend and Vue Frontend</title>
      <dc:creator>Yw Zhang</dc:creator>
      <pubDate>Sun, 18 Sep 2022 00:27:04 +0000</pubDate>
      <link>https://dev.to/zhng1456/easy-way-to-separate-java-backend-and-vue-frontend-3f5n</link>
      <guid>https://dev.to/zhng1456/easy-way-to-separate-java-backend-and-vue-frontend-3f5n</guid>
      <description>&lt;h2&gt;
  
  
  How to Run
&lt;/h2&gt;

&lt;p&gt;My complete project is on the github.&lt;a href="https://github.com/zhng1456/vue-java-separate" rel="noopener noreferrer"&gt;vue-java-separate&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git clone git@github.com:zhng1456/vue-java-separate.git


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open the project in IDEA and run Application.java&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyglp1iyproi4v8hhtgtk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyglp1iyproi4v8hhtgtk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Access &lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt; in chrome&lt;/p&gt;

&lt;p&gt;Explore the network tab in chrome dev tool,we find that &lt;a href="http://localhost:9090/api/users" rel="noopener noreferrer"&gt;http://localhost:9090/api/users&lt;/a&gt; returns the data of the table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy0p4x3zlb87wcyb7ge1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmy0p4x3zlb87wcyb7ge1.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post will help you create the project from scratch and separate backend and frontend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Java Backend
&lt;/h2&gt;

&lt;p&gt;First,create a maven project in you IDEA.&lt;/p&gt;

&lt;p&gt;File→New → Project&lt;/p&gt;

&lt;p&gt;create a module,New→module&lt;/p&gt;

&lt;p&gt;pom.xml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&amp;lt;?xml &lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt; &lt;span class="nv"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"UTF-8"&lt;/span&gt;?&amp;gt;
&amp;lt;project &lt;span class="nv"&gt;xmlns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt;
         xmlns:xsi&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
         xsi:schemaLocation&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;parent&amp;gt;
        &amp;lt;artifactId&amp;gt;vue-java-separate&amp;lt;/artifactId&amp;gt;
        &amp;lt;groupId&amp;gt;org.example&amp;lt;/groupId&amp;gt;
        &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;/parent&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;

    &amp;lt;artifactId&amp;gt;java-backend&amp;lt;/artifactId&amp;gt;

    &amp;lt;properties&amp;gt;
        &amp;lt;maven.compiler.source&amp;gt;8&amp;lt;/maven.compiler.source&amp;gt;
        &amp;lt;maven.compiler.target&amp;gt;8&amp;lt;/maven.compiler.target&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;

&amp;lt;/project&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create the first controller&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

package com.yw&lt;span class="p"&gt;;&lt;/span&gt;

import org.springframework.boot.SpringApplication&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.boot.autoconfigure.SpringBootApplication&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.web.bind.annotation.GetMapping&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.web.bind.annotation.RestController&lt;span class="p"&gt;;&lt;/span&gt;

/&lt;span class="k"&gt;**&lt;/span&gt;
 &lt;span class="k"&gt;*&lt;/span&gt; @author henry
 &lt;span class="k"&gt;*&lt;/span&gt; @date 2021/8/3
 &lt;span class="k"&gt;*&lt;/span&gt;/
@RestController
@SpringBootApplication
public class Application &lt;span class="o"&gt;{&lt;/span&gt;
    public static void main&lt;span class="o"&gt;(&lt;/span&gt;String[] args&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        SpringApplication.run&lt;span class="o"&gt;(&lt;/span&gt;Application.class, args&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    @GetMapping&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    public String hello&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;change port in application.yml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

server:
  port: 9090
  context-path: /


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the project and curl &lt;a href="http://localhost:9090" rel="noopener noreferrer"&gt;http://localhost:9090&lt;/a&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="s2"&gt;"http://127.0.0.1:9090/"&lt;/span&gt;
admin%


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Vue project
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Init
&lt;/h3&gt;

&lt;p&gt;use vue-cli create webpack project.&lt;/p&gt;

&lt;p&gt;I create vue project in root of the maven project.&lt;/p&gt;

&lt;p&gt;If you develop more complex project,you can put vue project in another git repository.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

vue init webpack vue-frontend

&lt;span class="nb"&gt;cd &lt;/span&gt;vue-frontend

&lt;span class="c"&gt;# run the application&lt;/span&gt;
npm run dev

&lt;span class="c"&gt;# build&lt;/span&gt;
npm run build


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After execute “npm run build”,the dist dictory is as follows&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspjeh4ty5txthebcmyu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fspjeh4ty5txthebcmyu8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Simplify js and css files
&lt;/h3&gt;

&lt;p&gt;Modify the webpack config files to make one js file and one css file in dist directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7v1t3rny7ud00k8n4a0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7v1t3rny7ud00k8n4a0w.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The detail is in &lt;a href="https://github.com/zhng1456/vue-java-separate/commit/6bffc0f591b960121a5378cd330b6c1ed5c8d74a" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Element UI
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm &lt;span class="nb"&gt;install &lt;/span&gt;element-ui &lt;span class="nt"&gt;-S&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;modify main.js&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

// The Vue build version to load with the &lt;span class="sb"&gt;`&lt;/span&gt;import&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt;
// &lt;span class="o"&gt;(&lt;/span&gt;runtime-only or standalone&lt;span class="o"&gt;)&lt;/span&gt; has been &lt;span class="nb"&gt;set &lt;/span&gt;&lt;span class="k"&gt;in &lt;/span&gt;webpack.base.conf with an alias.
import Vue from &lt;span class="s1"&gt;'vue'&lt;/span&gt;
import App from &lt;span class="s1"&gt;'./App'&lt;/span&gt;
import ElementUI from &lt;span class="s1"&gt;'element-ui'&lt;/span&gt;
import &lt;span class="s1"&gt;'element-ui/lib/theme-chalk/index.css'&lt;/span&gt;
Vue.use&lt;span class="o"&gt;(&lt;/span&gt;ElementUI&lt;span class="o"&gt;)&lt;/span&gt;
Vue.config.productionTip &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;

/&lt;span class="k"&gt;*&lt;/span&gt; eslint-disable no-new &lt;span class="k"&gt;*&lt;/span&gt;/
new Vue&lt;span class="o"&gt;({&lt;/span&gt;
  el: &lt;span class="s1"&gt;'#app'&lt;/span&gt;,
  components: &lt;span class="o"&gt;{&lt;/span&gt; App &lt;span class="o"&gt;}&lt;/span&gt;,
  template: &lt;span class="s1"&gt;'&amp;lt;App/&amp;gt;'&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Send HTTP Request
&lt;/h3&gt;

&lt;p&gt;Add a controller in java backend&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

package com.yw.controller&lt;span class="p"&gt;;&lt;/span&gt;

import com.yw.entity.User&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.web.bind.annotation.GetMapping&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.web.bind.annotation.RequestMapping&lt;span class="p"&gt;;&lt;/span&gt;
import org.springframework.web.bind.annotation.RestController&lt;span class="p"&gt;;&lt;/span&gt;

import java.util.ArrayList&lt;span class="p"&gt;;&lt;/span&gt;
import java.util.List&lt;span class="p"&gt;;&lt;/span&gt;

@RestController
@RequestMapping&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/api"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
public class UserController &lt;span class="o"&gt;{&lt;/span&gt;

    @GetMapping&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    public List&amp;lt;User&amp;gt; selectAllUsers&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        List&amp;lt;User&amp;gt; userList &lt;span class="o"&gt;=&lt;/span&gt; new ArrayList&amp;lt;&lt;span class="o"&gt;&amp;gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;int i &lt;span class="o"&gt;=&lt;/span&gt; 1&lt;span class="p"&gt;;&lt;/span&gt; i &amp;lt;&lt;span class="o"&gt;=&lt;/span&gt; 5&lt;span class="p"&gt;;&lt;/span&gt; i++&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            User user &lt;span class="o"&gt;=&lt;/span&gt; new User&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            user.setId&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            user.setName&lt;span class="o"&gt;(&lt;/span&gt;String.format&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"name%s"&lt;/span&gt;, i&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            user.setAddress&lt;span class="o"&gt;(&lt;/span&gt;String.format&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"address%s"&lt;/span&gt;, i&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            userList.add&lt;span class="o"&gt;(&lt;/span&gt;user&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return &lt;/span&gt;userList&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Call the controller in vue and show results with el-table&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;getAllUsers&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const response &lt;span class="o"&gt;=&lt;/span&gt; await fetch&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/api/users'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;await response.json&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&amp;lt;template&amp;gt;
  &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;h1&amp;gt;&lt;span class="o"&gt;{{&lt;/span&gt; msg &lt;span class="o"&gt;}}&lt;/span&gt;&amp;lt;/h1&amp;gt;
    &amp;lt;el-row&amp;gt;
      &amp;lt;el-button&amp;gt;default&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"primary"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;primary&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;success&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;info&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"warning"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;warning&amp;lt;/el-button&amp;gt;
      &amp;lt;el-button &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"danger"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;danger&amp;lt;/el-button&amp;gt;
    &amp;lt;/el-row&amp;gt;
    &amp;lt;el-table
      :data&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"userList"&lt;/span&gt;
      &lt;span class="nv"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"width: 100%"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &amp;lt;el-table-column
        &lt;span class="nv"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;
        &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt;
        &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"180"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &amp;lt;/el-table-column&amp;gt;
      &amp;lt;el-table-column
        &lt;span class="nv"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;
        &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt;
        &lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"180"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &amp;lt;/el-table-column&amp;gt;
      &amp;lt;el-table-column
        &lt;span class="nv"&gt;prop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;
        &lt;span class="nv"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"address"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &amp;lt;/el-table-column&amp;gt;
    &amp;lt;/el-table&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;script&amp;gt;
import &lt;span class="o"&gt;{&lt;/span&gt; getAllUsers &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'../services/user'&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;default &lt;span class="o"&gt;{&lt;/span&gt;
  name: &lt;span class="s1"&gt;'HelloWorld'&lt;/span&gt;,
  data &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      msg: &lt;span class="s1"&gt;'Welcome to Your Vue.js App'&lt;/span&gt;,
      userList: &lt;span class="o"&gt;[]&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,

  methods: &lt;span class="o"&gt;{&lt;/span&gt;
    getAllUsers&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      getAllUsers&lt;span class="o"&gt;()&lt;/span&gt;.then&lt;span class="o"&gt;(&lt;/span&gt;response &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        console.log&lt;span class="o"&gt;(&lt;/span&gt;response&lt;span class="o"&gt;)&lt;/span&gt;
        this.userList &lt;span class="o"&gt;=&lt;/span&gt; response
      &lt;span class="o"&gt;})&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  mounted&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    this.getAllUsers&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&amp;lt;/script&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Run Locally
&lt;/h3&gt;

&lt;p&gt;Before run the project,we need to config proxy in webpack config&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

devServer: &lt;span class="o"&gt;{&lt;/span&gt;
    proxy: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'/api/*'&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        target: &lt;span class="s1"&gt;'http://localhost:9090'&lt;/span&gt;,
        changeOrigin: &lt;span class="nb"&gt;true&lt;/span&gt;,
        secure: &lt;span class="nb"&gt;false&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run java backend and run vue project,access &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxym7c487pj4no2m3mgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxym7c487pj4no2m3mgg.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate  Backend and Frontend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to Separate
&lt;/h3&gt;

&lt;p&gt;The role of the front-end project is to provide the built js files and css files.If we can access the file by internet,all links are &lt;a href="http://fine.So" rel="noopener noreferrer"&gt;fine.&lt;/a&gt;So the solution to separate backend and frontend is &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Put the root of pages,index.html to java backend and use FreeMarker to show it&lt;/li&gt;
&lt;li&gt;Upload files to Google Cloud Storage&lt;/li&gt;
&lt;li&gt;Import js files and css files in index.html&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Add FreeMarker
&lt;/h3&gt;

&lt;p&gt;Add Maven dependency&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;spring-boot-starter-freemarker&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;config FreeMarker in application.yaml&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

server:
  port: 9090
  context-path: /

spring:
  freemarker:
    suffix: .ftl


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Create the directory templates in resources and create index.ftl&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width,initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;vue-frontend&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div id="app"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Upload Files to Google Cloud Storage
&lt;/h3&gt;

&lt;p&gt;We need to craete a bucket and the most important thing is to set &lt;strong&gt;Public to internet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkul5db3m9rbnrbwl07i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxkul5db3m9rbnrbwl07i.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then upload js files and css files(you can find this files in your dist directory of vue project)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vrl8nvtqd5y7a2ixpov.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4vrl8nvtqd5y7a2ixpov.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click “Copy URL” and confirm that you can access it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Import cloud files in template
&lt;/h3&gt;

&lt;p&gt;Import files in index.ftl&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&amp;lt;&lt;span class="o"&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class="nb"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;meta &lt;span class="nv"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"utf-8"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;meta &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"viewport"&lt;/span&gt; &lt;span class="nv"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"width=device-width,initial-scale=1.0"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;&lt;span class="nb"&gt;link &lt;/span&gt;&lt;span class="nv"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://storage.googleapis.com/webpack-frontend/app.css"&lt;/span&gt; &lt;span class="nv"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"stylesheet"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;title&amp;gt;vue-frontend&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"app"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/div&amp;gt;
&amp;lt;script &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"text/javascript"&lt;/span&gt; &lt;span class="nv"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://storage.googleapis.com/webpack-frontend/app.js"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run java backend&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/bin/java &lt;span class="nt"&gt;-XX&lt;/span&gt;:TieredStopAtLevel&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nt"&gt;-noverify&lt;/span&gt; &lt;span class="nt"&gt;-Dspring&lt;/span&gt;.output.ansi.enabled&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="nt"&gt;-javaagent&lt;/span&gt;:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar&lt;span class="o"&gt;=&lt;/span&gt;64768:/Applications/IntelliJ IDEA.app/Contents/bin &lt;span class="nt"&gt;-Dcom&lt;/span&gt;.sun.management.jmxremote &lt;span class="nt"&gt;-Dspring&lt;/span&gt;.jmx.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="nt"&gt;-Dspring&lt;/span&gt;.liveBeansView.mbeanDomain &lt;span class="nt"&gt;-Dspring&lt;/span&gt;.application.admin.enabled&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="nt"&gt;-Dfile&lt;/span&gt;.encoding&lt;span class="o"&gt;=&lt;/span&gt;UTF-8 &lt;span class="nt"&gt;-classpath&lt;/span&gt; /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/legacy8ujsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/openjsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/rt.jar:/Users/yunwang/workspace/vue-java-separate/java-backend/target/classes:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.1.6.RELEASE/spring-boot-starter-web-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter/2.1.6.RELEASE/spring-boot-starter-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot/2.1.6.RELEASE/spring-boot-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.1.6.RELEASE/spring-boot-autoconfigure-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.1.6.RELEASE/spring-boot-starter-logging-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/yunwang/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/yunwang/.m2/repository/org/slf4j/slf4j-api/1.7.26/slf4j-api-1.7.26.jar:/Users/yunwang/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.11.2/log4j-to-slf4j-2.11.2.jar:/Users/yunwang/.m2/repository/org/apache/logging/log4j/log4j-api/2.11.2/log4j-api-2.11.2.jar:/Users/yunwang/.m2/repository/org/slf4j/jul-to-slf4j/1.7.26/jul-to-slf4j-1.7.26.jar:/Users/yunwang/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/Users/yunwang/.m2/repository/org/springframework/spring-core/5.1.8.RELEASE/spring-core-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-jcl/5.1.8.RELEASE/spring-jcl-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/yaml/snakeyaml/1.23/snakeyaml-1.23.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.1.6.RELEASE/spring-boot-starter-json-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.9.9/jackson-databind-2.9.9.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.9.0/jackson-annotations-2.9.0.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.9.9/jackson-core-2.9.9.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.9.9/jackson-datatype-jdk8-2.9.9.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.9.9/jackson-datatype-jsr310-2.9.9.jar:/Users/yunwang/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.9.9/jackson-module-parameter-names-2.9.9.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.1.6.RELEASE/spring-boot-starter-tomcat-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.21/tomcat-embed-core-9.0.21.jar:/Users/yunwang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.21/tomcat-embed-el-9.0.21.jar:/Users/yunwang/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.21/tomcat-embed-websocket-9.0.21.jar:/Users/yunwang/.m2/repository/org/hibernate/validator/hibernate-validator/6.0.17.Final/hibernate-validator-6.0.17.Final.jar:/Users/yunwang/.m2/repository/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar:/Users/yunwang/.m2/repository/org/jboss/logging/jboss-logging/3.3.2.Final/jboss-logging-3.3.2.Final.jar:/Users/yunwang/.m2/repository/com/fasterxml/classmate/1.4.0/classmate-1.4.0.jar:/Users/yunwang/.m2/repository/org/springframework/spring-web/5.1.8.RELEASE/spring-web-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-beans/5.1.8.RELEASE/spring-beans-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-webmvc/5.1.8.RELEASE/spring-webmvc-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-aop/5.1.8.RELEASE/spring-aop-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-context/5.1.8.RELEASE/spring-context-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/spring-expression/5.1.8.RELEASE/spring-expression-5.1.8.RELEASE.jar:/Users/yunwang/.m2/repository/org/springframework/boot/spring-boot-starter-freemarker/2.1.6.RELEASE/spring-boot-starter-freemarker-2.1.6.RELEASE.jar:/Users/yunwang/.m2/repository/org/freemarker/freemarker/2.3.28/freemarker-2.3.28.jar:/Users/yunwang/.m2/repository/org/springframework/spring-context-support/5.1.8.RELEASE/spring-context-support-5.1.8.RELEASE.jar com.yw.Application

  &lt;span class="nb"&gt;.&lt;/span&gt;   ____          _            __ _ _
 /&lt;span class="se"&gt;\\&lt;/span&gt; / ___&lt;span class="s1"&gt;'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '&lt;/span&gt;_ | &lt;span class="s1"&gt;'_| | '&lt;/span&gt;_ &lt;span class="se"&gt;\/&lt;/span&gt; _&lt;span class="sb"&gt;`&lt;/span&gt; | &lt;span class="se"&gt;\ \ \ \&lt;/span&gt;
 &lt;span class="se"&gt;\\&lt;/span&gt;/  ___&lt;span class="o"&gt;)&lt;/span&gt;| |_&lt;span class="o"&gt;)&lt;/span&gt;| | | | | &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;_| |  &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="s1"&gt;'  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2022-09-18 06:21:04.801  INFO 3257 --- [           main] com.yw.Application                       : Starting Application on Zhangs-MacBook-Air.local with PID 3257 (/Users/yunwang/workspace/vue-java-separate/java-backend/target/classes started by yunwang in /Users/yunwang/workspace/vue-java-separate)
2022-09-18 06:21:04.806  INFO 3257 --- [           main] com.yw.Application                       : No active profile set, falling back to default profiles: default
2022-09-18 06:21:05.182  INFO 3257 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 9090 (http)
2022-09-18 06:21:05.191  INFO 3257 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-09-18 06:21:05.191  INFO 3257 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.21]
2022-09-18 06:21:05.229  INFO 3257 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-09-18 06:21:05.230  INFO 3257 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 369 ms
2022-09-18 06:21:05.307  INFO 3257 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService '&lt;/span&gt;applicationTaskExecutor&lt;span class="s1"&gt;'
2022-09-18 06:21:05.342  INFO 3257 --- [           main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page template: index
2022-09-18 06:21:05.398  INFO 3257 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 9090 (http) with context path ''
2022-09-18 06:21:05.403  INFO 3257 --- [           main] com.yw.Application                       : Started Application in 15.777 seconds (JVM running for 21.088)
```

Notice “Adding welcome page template: index” and it means your config is correct.

Access http://localhost:9090

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4s3qabqrn3vhwx1hcnwl.png)
### More convenient Way to Upload files

It is too troublesome to manually upload the file every time, is there a more convenient way?

Yes,we can upload files by node client of Google Cloud Storage.

I will detail this part in another post [how-to-deploy-vue-frontend](https://dev.to/zhng1456/how-to-deploy-vue-frontend-17ph).
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>vue</category>
      <category>googlecloud</category>
      <category>beginners</category>
      <category>java</category>
    </item>
    <item>
      <title>How To Monitor Http traffic Of Third Party Service</title>
      <dc:creator>Yw Zhang</dc:creator>
      <pubDate>Sun, 04 Sep 2022 08:54:02 +0000</pubDate>
      <link>https://dev.to/zhng1456/how-to-monitor-http-traffic-of-third-party-service-4i1m</link>
      <guid>https://dev.to/zhng1456/how-to-monitor-http-traffic-of-third-party-service-4i1m</guid>
      <description>&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;The company purchased a third-party service and deployed it on the company's machine in the form of a jar package.This service is on a critical data link, and the concurrency is very high. The service http request appears 500, which is what we cannot receive.&lt;/p&gt;

&lt;p&gt;Even without the source code, we also need to monitor HTTP requests to provide detailed information to the provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ideas to Solve the Problem
&lt;/h2&gt;

&lt;p&gt;My first thought was to use java agent to monitor.Java agents are a special type of class which, by using the Java Instrumentation API, can intercept applications running on the JVM, modifying their bytecode.&lt;/p&gt;

&lt;p&gt;Another solution is to capture network traffic. My core requirement is to monitor requests with a status code of 5xx, so capturing traffic is more suitable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Capture network traffic
&lt;/h2&gt;

&lt;p&gt;Tcpdump can capture traffic but needs parsing to be more suitable for reading.&lt;/p&gt;

&lt;p&gt;httpry is a tool designed for displaying and logging HTTP traffic.&lt;/p&gt;

&lt;p&gt;Nice!This is the tool I was looking for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install httpry on Centos
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;yum&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;epel&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;release&lt;/span&gt;

&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;yum&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;httpry&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Filter Response with a Status Code other than 200&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;httpry&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;dest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tcp dst port 80 and tcp[((tcp[12:1] &amp;amp; 0xf0) &amp;gt;&amp;gt; 2)+8:4] != 0x20323030&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output in test.log like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;403&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;403&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;span class="mi"&gt;2022&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;34&lt;/span&gt;     &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;  &lt;span class="mf"&gt;192.168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;       &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Manager Large Data Volume Output File
&lt;/h3&gt;

&lt;p&gt;All the information is typed into one file, this file will be very large.&lt;/p&gt;

&lt;p&gt;You need another tool:logrotate.&lt;/p&gt;

&lt;p&gt;I want to organize the files by date and I create the file logrotate.conf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="sr"&gt;/xxxx/&lt;/span&gt;&lt;span class="nx"&gt;xxxxx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;notifempty&lt;/span&gt;
        &lt;span class="nx"&gt;copytruncate&lt;/span&gt;
        &lt;span class="nx"&gt;dateext&lt;/span&gt;
        &lt;span class="nx"&gt;dateformat&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;Y&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;
        &lt;span class="nx"&gt;olddir&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;xxx&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;backup&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following command can debug the process&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;logrotate -d xxx/lograte.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add timed tasks through ctontab，crontab will execute the rotate according to the config and We will get a file named http.log.20220815.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/jbittel/httpry"&gt;httpry&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/logrotate/logrotate"&gt;logrotate&lt;/a&gt;&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>tutorial</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
