Hello everyone, I am quick-frozen fish 🐟, a front end of water system 💦, like colorful whistle 💐, continuous sand sculpture 🌲, I am a good brother of the next door Cold grass Whale, I just started to write an article.

If you like my article, you can follow ➕ to like it, inject energy into me, and grow with me

Read this article 📖

1. You will learn how to build the simplest JS base library 0-1 quickly

2. You will learn how to quickly set up a Node service

3. Will you learn how to write a Vite plug-in side-by-side pit

Warehouse address:info-js

Preface 🌵

The creation of this library from a colleague suddenly one day when writing front-end Web application raised a demand, need to obtain some information about the client, so began the compilation of this library

Demand 💻

  • Obtain information about the client browser

  • Obtain client information

  • Get WebApp information

  • Obtain the IP address and related information of the user

  • .

Development idea ⭐

1. Initialize the project first

NPM init initializes our base library called InfoJs

2. Obtain information about the client browser

Since it is to obtain browser-related information, we are sure that our WebAPI provides the corresponding interface, we only need to encapsulate the properties of the Window object into our information object, part of the code is omitted in the figure, the source code address at the end of the article

class BrowserInfo {

    // The client browser Window object
    private _window: Window
    // Client browser object
    private _navigator: Navigator
    // Client browser platform and version information
    private _appVersion: string = 'unknown'
    // The value of the user-Agent header sent by the client browser to the server
    private _userAgent: string = 'unknown'
    // The client runs on the browser's operating system platform
    private _platform: string = 'unknown'
    // The resolution of the client browser
    private _screenResolution: string = 'unknown'
    // Whether the client is a mobile device
    private _isMobileDevice: boolean = false
    // Client information object
    private _client: ClientInfo | null = null

    // The current app package name
    private _appPackageName:string='unknown'
    // The app version of the current project
    private _appVersionCode:string='unknown'
    // The current app running environment variable
    private _viteMode:string='unknown'
    // Client IP address
    private _appIpAddress:string='unknown'
    // Client IP address country
    private _appIpCountry:string='unknown'
    //WebApp mode
    private _appMode:string='unknown'

   / /...

export {BrowserInfo}


Copy the code

3. The window object information is easy to obtain, but how to obtain the user IP

The first thing we need to know is that the IP address is the address that identifies the host on the network, so how do we get it? It’s only through the network. Then we can send a request from the base library to the back end, and the back end has a request header with an IP address, and then we get the IP address and we send it back.

Front-end writing 🎃:

 // Obtain IP and country information
        fetch('http://infojs.xyz/api/getipaddress')
            .then(response= > response.json())
            .then(data= >{
                this._appIpAddress=data.ipAddress;
                this._appIpCountry=data.ipCountry;
            })
            .catch(e= >console.log('Failed to obtain the client IP address and the geographic location of the IP address ~'))
Copy the code

Back-end writing 🐚(node):

Express is used here. Pay attention to cross-domain access

  // Import express module
const express = require('express');
// Import the cross-domain access module
const cors = require('cors');
// Create a server instance for Express
const app = express();
Copy the code

Here, my back-end service is referred to by Cloudflare(the world’s fastest CDN), so the request header contains “CF-connecting – IP” and “CF-IPCountry” headers. If there is no CDN, you can use the following headers to retrieve it and return it to the client:

If the HTTP Header contains client-IP, it is treated as the real IP first. If the HTTP Header contains X-Forwarded-For, this Header is assumed to be the real IP address. If neither exists, REMOTE_ADDR is taken as the real IP.

// Obtain the CLIENT IP address
module.exports.getClientIpAddress=(req,res) = > {
    console.log(req.headers)
    let ipAddress= req.headers["cf-connecting-ip"]????'unKnow'
        let ipCountry= req.headers["cf-ipcountry"]????'unKnow'
    res.json({
        "ipAddress":ipAddress,
        "ipCountry":ipCountry
    })
}
Copy the code

4. How to obtain WebApp information

A lot of webApp information can be obtained in the project package.json file, but such information can only be obtained during compilation, such as environment variable parameters, etc. How to solve this problem? This can be solved by developing a server plug-in, and here we are using Vite, so write a Vite plug-in

Write plug-ins:

const path = require("path")
const cwd = process.cwd();
let pkgManifest = require(path.join(cwd, 'package.json'));
module.exports = function () {
    let appVersion = pkgManifest.version
    let appPackageName = pkgManifest.name
    let viteMode = undefined
    const virtualFileId = '@infoJs-plugin-virtual-module'
    return {
        name: 'infoJs-plugin'.// Yes, will be displayed in warning and error
        config: (UserConfig, {mode}) = > {
            viteMode = mode;
        },
        resolveId(id) {
            if (id === virtualFileId) {
                return virtualFileId
            }
        },
        load(id) {
            if (id === virtualFileId) {
                return `
                export const appInfo = {
                "appVersion":"${appVersion}",
                "appPackageName":"${appPackageName}",
                "viteMode":"${viteMode}",} `}}}}Copy the code

Get package.json file objects through this plug-in, and then export our objects through a virtual directory

 const virtualFileId = '@infoJs-plugin-virtual-module'
Copy the code

Here’s the question: how do we inject the virtual directory exported by our plug-in into another library file?

Here we introduce the virtual path directly into the library file, ts will report an error because it does not exist, here we ignore //@ts-ignore

//@ts-ignore
import {appInfo} from '@infoJs-plugin-virtual-module'
Copy the code

There will still be problems with the path, and the compiler will also report parsing errors

If a virtual path is introduced in the library, it should be excluded from the package so that Vite ignores it

vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import infoJsPlugin from '@imf/infojs-plugin'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(),infoJsPlugin()],
  // Optimize package dependencies
  optimizeDeps: {exclude: ['@infoJs-plugin-virtual-module']}})Copy the code

So we have completed all the requirements, see here may be a little bit confused, I have uploaded all the code to github, interested partners can go to see the source ^_^

Warehouse address: info-js

Conclusion 🌛

So my first article is over, the purpose of the article is actually very simple is the summary and output of daily work, no matter whether the output of dishes is always meaningful, but also hope to know more like-minded friends through the article, if you also like to toss, welcome to add my friends, sand sculpture, progress together.

Making 🤖 : sudongyu

Personal blog 👨💻: Frozen fish blog

Vx 👦 : sudongyuer

Write in the last

Guys, if you like my words, give 🐟🐟 a thumbs up 👍 or follow ➕ to support me the most.