Hello, I am Cangcang Liangliang, a front-end developer. At present, I am publishing some interesting and knowledge about front-end learning on Nuggets, Zhihu and my personal blog. Welcome to follow me.


Cause 1.

After a year, the script series of oil Monkey came again. The reason was that when I was in the shower that day, I suddenly had a flash of inspiration. I realized that in the front-end development, there were a lot of work that was completely mechanical and had no difficulty, but it took unusually long time! It’s just a bunch of table fields.

So far I still before the development of the millions of ERP project, the project list is very much, there are about hundreds of, and each list has a lot of fields, usually all around 20 fields, and then end write will return to a lot of fields in the corresponding interface, you need to return from the field in the selected list required fields.

Maybe one or two is fine, but pairing dozens of lists with hundreds of fields one by one is time-consuming and exhausting, so I had an idea at this time: Is there a way to extract the list fields from the prototype graph and compare them with the field annotations under the interface in Swagger? If they are correct, the table header code that Antd can use will be generated. If they are not correct, the unmatched fields will be displayed, and then the unmatched fields will be matched with naked eyes. If the fields are still not found, send them to the back end for the back end to add them.

When I thought of this possibility, I immediately wanted to implement it. Then I remembered that I had done something with the Oil Monkey script a year ago, so I suddenly wondered if this could be implemented with the oil Monkey script.

2. Oilmonkey script

I’ve written several articles on Oilmonkey scripts in the last year, where I mentioned the ability to develop extremely complex scripts, even engineering level scripts, with Webpack packaging, as well as using packages on NPM.

But because of the complexity of WebPack configuration, I didn’t consider using webPack in the first place. Instead, I thought of another zero-configuration packaging tool: Parcel.

Unfortunately, this failed, and I didn’t know why the method of importing external resources directly through oilmonkey via parcel wrapped JS file would fail, so I came up with a tool for packing JS files: Rollup.

Unfortunately, it also failed. I don’t know why there would be an error after the introduction of oil Monkey, so I gave up resistance at this time and chose Webpack for packaging. As expected, the JS files packed by Webpack were introduced into oil Monkey without any problems.

Since I’ve done this before, and concluded the article on the powerful Tampermonkey script development environment, I won’t go into the basics of the Monkey.

2.1 Benefits of packaging

Why pack via Webpack?

Because in writing some complex scripts, we often need to use a lot of libraries, and also the script for modular, into a lot of files, if you still want to write some CSS style at the same time, you also can directly write CSS files or Less and Sass, through webpack these files can be unified, Package it into a JS and import it through the external import provided by the oilmonkey.

As I’ve gotten more comfortable with React, I’ve had to implement automatic alignment of fields as well. I’m a big fan of TypeScript because it gives your code more cues and prevents you from making stupid mistakes.

Antd is a UI component library. It not only solves some style problems, but also solves many interactive aspects, such as its Form Form. It is also very easy to use.

To sum up, if you are developing an oilmonkey script, packaging via WebPack is a great option.

3. jQuery

As I said in my article a year ago, jQuery is a great library to learn from, because there is nothing more convenient for writing oilmonkey scripts than using jQuery to extract information from an interface.

Because of the ease of use of jQuery, you can easily extract the information you want from the interface. While you can achieve similar results with re, jQuery code is faster and less error-prone than re.

4. The regular

Writing scripts, very many cases will use the re, because to accurately match the corresponding character, re is your best choice, when doing some automatic generation code tools, because it involves the problem of character matching, learn to re is very important.

Here’s a great regex test site: RegExr: Learning, build and Test the regular expression Test RegEx, because sometimes you can’t judge you write regular right, so this time you can Test on the website first, if the Test results meet your expectations, then copies the regular expression to Test in your project, it is easy to write up the regular, It is also very simple to use. Go to the website and click on it for two times to understand how to use it.

5. Crawler foundation

If you want to extract some information from the interface, you need to have some basic knowledge of crawlers and how to retrieve some information from the interface.

In theory, all the information on a web page can be extracted using regular expressions, but since regular expressions can be error-prone in the writing process, jQuery can effectively extract the page data.

Here is a page information extraction of douban ranking that 90% of people will choose when crawler entry.

Examples of 6.

In fact, I have implemented the script above, but due to swagger has the interface information of the company project, so I will not use that script as a demonstration.

So here I take the douban ranking information extracted by jQuery as a demonstration:

The main function is to enter the name of the movie in the input box, and then match and display the movie-related information:

6.1 Triggering Event Building

To execute the code you have written, you usually need a button, an input box or other elements to trigger. In the development of this script, I used Antd button +Antd modal box +Antd input box these three components to build the script.

6.2 Final Effect

The end result is something like this. The code isn’t that hard.

Paste the final code here:

import { Button, ConfigProvider, Form, Modal } from "antd";
import "antd/dist/antd.css";
import TextArea from "antd/es/input/TextArea";
import zhCN from "antd/lib/locale/zh_CN";
import * as $ from "jquery";
import { useState } from "react";
import { render } from "react-dom";

interface InfoDataList {
  /** The name of the movie */
  title: string;
  /** 分数 */
  score: string;
  /** Number of comments */
  number: string;
  /** 简介 */
  info: string;
}

function AppButton() {
  const [infoDataList, setInfoDataList] = useState<InfoDataList[]>([]);

  const [showData, setShowData] = useState<InfoDataList>();

  const [visible, setVisible] = useState(false);

  return (
    <>
      <Button
        onClick={()= >*/ const info: InfoDataList[] = []; $(".info"). Each (function (this) {const infoItem: InfoDataList = {} as InfoDataList; // Here is all the information, $(this).find(".title").each(function (this, If (index === 0) infoitem.title = this.innerhtml; }); $(this).find(".rating_num"). Each (function (this) {infoitem.score = this.innerhtml; }); $(this).find(". Star > span:nth-child(4)"). Each (function (this) {infoitem.number = this.innerhtml; }); $(this).find(".inq"). Each (function (this) {infoitem.info = this.innerhtml; }); info.push(infoItem); }); setInfoDataList(info); // Open the popover setVisible(true); }} style={{position: "fixed", right: "100px", bottom: "100px"}}</Button>
      <Modal
        title="Auto field matching"
        visible={visible}
        centered
        destroyOnClose
        width={1000}
        onCancel={()= > {
          setVisible(false);
        }}
      >
        <Form
          preserve={false}
          onValuesChange={async (value) = >{// If there is no value, it does not match if (! value.text) { setShowData(undefined); return; } const rgx = RegExp(value.text); const data = infoDataList.find((item) => rgx.test(item.title)); setShowData(data); }} ><Form.Item name="text">
            <TextArea rows={10} />
          </Form.Item>
        </Form>{/* display the correct fields */}<ul>
          <li>Movie title: {showData? .title}</li>
          <li>Score: {showData? .score}</li>
          <li>{showData? .number}</li>
          <li>Introduction: {showData? .info}</li>
        </ul>
      </Modal>
    </>
  );
}

// Add a div as the React entry file
$("body").append(`<div id="ccll-app"/>`);

render(
  <ConfigProvider locale={zhCN}>
    <AppButton />
  </ConfigProvider>.document.getElementById("ccll-app")
);Copy
Copy the code

7. Webpack configuration

The following is a set of webpack.config.js that I built and used myself, adding support for CSS, TypeScript, Less, and JavaScript compatibility processing, you can directly copy the following code to try the past.

const { resolve } = require("path");

module.exports = {
  entry: ["./index.js"].output: {
    path: resolve(__dirname, "build"),
    filename: "index.js".publicPath: "/",},module: {
    rules: [{test: /.(js|jsx|mjs)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "babel-loader".options: {
              // Preset: indicates what compatibility processing Babel is doing.
              presets: [["@babel/preset-env",
                  {
                    corejs: {
                      version: 3,},// Load as needed
                    useBuiltIns: "usage"],},"@babel/preset-react",],},},],}, {test: /.tsx? $/,
        use: "ts-loader".exclude: /node_modules/}, {test: /.css$/.// Which loaders are used for processing
        use: [
          // The sequence of loader execution in the use array is from right to left and from bottom to top
          // Create a style tag and insert the js style resource into the head
          "style-loader".// Change the CSS file into a commonJS module and load the js file with the style string
          "css-loader",]}, {test: /.less$/.// Which loaders are used for processing
        use: [
          // The sequence of loader execution in the use array is from right to left and from bottom to top
          // Create a style tag and insert the js style resource into the head
          "style-loader".// Change the CSS file into a commonJS module and load the js file with the style string
          "css-loader",
          {
            loader: "less-loader".options: {
              lessOptions: {
                javascriptEnabled: true,},},},],},resolve: {
    extensions: [".tsx".".ts".".js"],},mode: "production".devtool: "source-map"}; CopyCopy the code

8. The last

This article does not use my final script to demonstrate, but to simulate another example, mainly to serve as a starting point, I want to express that the oil Monkey is neglected by our front-end developers, in fact, it is a very good tool to improve development efficiency.

As you can see from this article, there are a lot of things you need to know to write a script, especially jQuery and re. Of course, if you are familiar with native JS, you can use native JS code instead of jQuery code.

In my own experience with oilmonkey scripts, jQuery is used in almost every script, although it is not very deep, mainly to extract interface information, and regex is used a lot.

In fact, there is still a problem left here. After React+Antd is introduced, the packaging time often reaches about 10s, while the packaged code usually reaches about 2M. The next article will explain how to use CDN introduction in oil monkey to reduce the packaging time to about 1s and the code volume to about tens of KB.

Through this eureka moment, I thought that when writing business code at ordinary times, some repetitive mechanical work can be handed over to scripts to achieve, improve their development efficiency, to be a programmer off work on time.