background

The current project uses code burying points. Due to historical reasons, there are two (actually three) sets of such intrusive burying points at the same time, which are APM and exposure statistics reported through the company interface (historical reasons and trackOsrRecord are also interface reporting statistics). Although the code burying point can be refined to report data, with the increase of intrusive burying point, there are the following problems

  • Business requirements are frequently iterated, and buried codes are deleted by mistake, leading to online statistics loss;
  • Repeated buried point, different products to a wave of buried point demand, there are a lot of repeated buried point;
  • The meaning of the buried point field in the project is not clear, so I don’t know why the point is used;
  • To make matters worse by coupling the business, there are several ways to bury the project.
  • Multi-project use, each project introduction is written differently, not only lose reusability, but also increase the difficulty of code reading.

Such as:

// One of the buried points: APM
this.$apm.addCountReocord('record'.'action', {
  name: 'complete_task_from_card'
})
// Exposure interface
this.eventReport({
  action: 'join_position'.channel: null.data: null.key: 'event_iphone'.module: ' '.path: ' '.trigger: 'click'
})
// Buried point of the second sibling, browse record addRecord report
function trackRecord(params) {
  / /... Other Params filtering operations, end
  await addRecord(params) AddRecord is an interface report
},
Copy the code

Take measures to

In view of burying point is an indispensable part of monitoring content, in order to better standardize the use of burying point, the code burying point in the project needs to do the following optimization:

  • Unified buried point method: extract buried point method, NPM package introduction and use, reusable multi-project;
  • Buried semantics: buried method calls force the role (or details) of buried points;
  • Generate route and buried point mapping: Passwebpack pluginGenerate the relationship between page routing and buried points, so that you can intuitively see the distribution of buried points throughout the project (but also specific to which line of code which column).

The above is still the imperative burial point, interested partners can also be in the project declarative burial point to make the burial point cleaner

// Expected call
this.$trackReport({
  key: 'view_iphone_detail'.msg: 'APM_iphone page _ Click to view detail'
})
Copy the code

Unified buried method calls

There’s not a lot of meandering around here, it’s just a strategy for multiple buried methods based on type type, calling different buried methods with parameters type and params. For example, using the NPM package track to expose trackReport is the policy method, receiving params parameter, config burying the required configuration such as token uid getDefaultTrackConfi is actually to get the default config, In use, coverage can be done according to different desires, such as covering the INTERFACE URL reported by exposure interface. Finally mounted into the Vue Prototype chain for global convenience.

// Initialize the buried point method and mount it to the prototype chain
import Vue from 'vue'
import { trackReport, getDefaultTrackConfig } from 'track'
/** * description: the parameter corresponding to the buried event, where the key of the object is the key of the call to match. * this.$trackReport({* key: 'view_iphone_detail', * MSG: 'apm_iphone ') */
const eventMapParams = {
  view_iphone: () = > ({
    type: 'apm'.params: {
      name: 'iphone'.type: 'view'.spans: { name: 'view_iphone_list'}}}),view_iphone_detail: (that) = > ({
    // that is the context of the currently invoked component this to get dynamic data
    type: 'apm'.params: {
      name: 'iphone_detail'.type: 'view_detail'.spans: { money: that.money }
    }
  })
}

export const initTrack = ({ token, userInfo }) = > {
  const config = getDefaultTrackConfig({ token, userInfo })
  Vue.prototype.$trackReport = function(info) {
    // Match params based on the information passed in info
    const { key } = info || {}
    const params = eventMapParams[key](this)
    trackReport(params, config)
  }
}
Copy the code

In particular, eventMapParams gets the params of the current buried point event (there is no other way to manage params……). After all, buried points report different parameters, unified here is more intuitive and easier to manage, than scattered in the business components

NPM package development, release

The overall project is as follows:



The initialization and packaging configurations are as follows

Install the TypeScript

It is highly recommended to use TypeScript for strong type checking and very friendly hints.

For example, a comment in the form of /** */ can indicate the TS type, and the editor will have a better indication



tsconfig.jsonThis file specifies the root file and compilation options used to compile the projectTs Official Documentation

// install yarn add tslib typescript -d // Generate ts configuration file, tsconfig.json can be used to configure compiled JS versions, tslint checks, etc. NPX TSC --initCopy the code

Rollup packages configuration

We all know that Rollup has a much better tree-shaking library for development, but webPack is fine too. Look at this good article

  • Rollup analyzes the flow during compilation and packaging, and thanks to ES6 static modules (exports and imports cannot be modified at run time), we can determine which code we need at package time.
  • Webpack itself can only mark unused code and not remove it when it is packaged, and it is tools like UglifyJS, Babili, Terser, etc., that identify unused code and do tree-shaking. In simple terms, the compression tool reads the webPack results and removes unused code from the bundle prior to compression

Installation:

yarn add rollup -D
Copy the code

Create the rollup.config.js file and configure it as follows:

// Identify and translate ts
import typescript from '@rollup/plugin-typescript'
// Parsing introduces NPM packages to allow us to load third-party modules
import resolve from 'rollup-plugin-node-resolve'
// ES6 + JavaScript parser, Mangler and compressor toolkit
import { terser } from 'rollup-plugin-terser'

import pkg from './package.json'

// Add the current version record to the end
const footer = ` if(typeof window ! == 'undefined') { window._TrackVersion = '${pkg.version}'
}`
export default {
  input: './src/index.ts'.output: [{file: pkg.main,
      format: 'umd',
      footer,
      name: 'Track'.sourcemap: true.plugins: [terser()]
    }
  ],
  context: 'window'.plugins: [typescript(), resolve()]
}
Copy the code

Debugging and publishing

NPM link See NPM config.

Run NPM link/YARN link in the package root directory. In this case, a symbolic link is created in {prefix}/lib/node_modules/. The symbolic link links to the package where NPM link runs the command.

NPM link packageName = NPM link packageName = NPM link packageName

PackageName is taken from package.json’s name field. Executing the NPM link packageName command creates a symbolic link from the globally installed packageName to node_modules in the current file

NPM unlink Disconnects the link

NPM unlink in project –no-save package && NPM install NPM unlink in project

NPM login && NPM publish

NPM login Account and password for logging in to the NPM NPM publish Publish to the NPM

You can use Github Actions to automate publishing and reduce manual operations. NPM_TOKEN is configured in Github, and the token is specified in github Actions.

name: dry
on:
  pull_request:
    branches:
      - main The main branch is triggered by pr and the push branch is triggered by updates
jobs:
  build:
    runs-on: Ubuntu 18.04
    steps:
      - uses: actions/checkout@v2	   # checkout code
      - uses: actions/setup-node@v1  # integration node
      - uses: actions/cache@v2 			 # cache
        with:
          path: ~/.npm
          key: The ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: | ${{ runner.os }}-node-      - name: install and test
        run: | npm install npm run test      - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
      - name: publish
        if: ${{contains(github.ref, 'refs/tags/')}} Check git tags
        run: | npm run build npm publish --access publicCopy the code

The Webpack Plugin generates a route-buried map

throughwebpack pluginGenerate the relationship between page routing and buried points, so that the distribution of buried points of the whole project can be seen visually (and can be specific to which line and column of the code). The final result is as follows:



I will not expand it here, but attach the diagram:



Plugin runs in the child process, the generated JSON can be used to render the interface, so you can intuitively see the entire project buried point distribution, can happily with the product ðŸĪš fencing.

conclusion

The above is to sort out some records of the company buried point, the ability is limited, if we have a better way to sort out the code buried point, welcome 👏ðŸŧ message.