RxJS+WebPack+TS实现组件间的松耦合

本文将介绍如何通过RxJS+TS实现模块间的松耦合。所谓松耦合是指模块间不能存在显示的引用关系。公司项目中经常看到junior程序员写出如下的代码:

var moduleA = {
  foo: function() {
    moduleB.doSomeThing();
    moduleC.doSomeThing();
  }

  dummy: function() {}
}

var moduleB = {
  doSomeThing: function() {}
  doAnotherThing: function() {
    moduleA.dummy();
  }
}

var moduleC = {
  doSomeThing: function() {}
}

显然这种代码极其糟糕,模块间互相引用,一旦修改就会漏洞百出。 那么作为tech manager,我提出了几种修改建议。 首先,建立demo环境

npm init -y
npm install rxjs ts-loader typescript webpack webpack-dev-server --save
npm install webpack-cli --save-dev

tsconfig.json

{
    "compilerOptions": {
      "outDir": "./dist/",
      "noImplicitAny": true,
      "module": "es6",
      "moduleResolution": "node",
      "sourceMap": true,
      "target": "es6",
      "experimentalDecorators": true,
      "typeRoots": [
        "node_modules/@types"
      ],
      "lib": [
        "es2017",
        "dom"
      ]
    }
  }

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/index.ts',
    devtool: 'inline-source-map',
    module: {
        rules: [
        {
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/
        }
        ]
    },
    resolve: {
        extensions: [ '.tsx', '.ts', '.js' ]
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
};

public/index.html

<html>
    <head>
        <title>Demo</title>
    </head>
    <body>
        <style>
            #app {
                width: 100%;
                height: 400px;
                display: flex;
            }
            #toolDiv {
                width: 100%;
                height: 50px;
                background-color:cornsilk;
            }
            #leftDiv {
                width: 50%;
                height: 100%;
                background-color:chocolate;
            }
            #rightDiv {
                width: 50%;
                height: 100%;
                background-color: burlywood;
            }
        </style>
        <div id="toolDiv">
            <input type="button" id="btnCount" value="+1" />
            <input type="button" id="btnMinus" value="-1" />
        </div>
        <div id="app" style="width:100%; height: 400px;">
            <div id="leftDiv">
                <p id="leftCount">0</p>
            </div>
            <div id="rightDiv">
                <p id="rightCount">0</p>
            </div>
            <div id="middleDiv">
                <p id="middleCount">0</p>
            </div>
        </div>
    </body>
    <script src="/bundle.js"></script>
</html>

src/index.ts //方案一

namespace Index {
    
    type addClickEvent = () => void;

    class ToolBar {
        private btnAdd: HTMLElement;
        private addCB: addClickEvent

        constructor(_addCallBack: addClickEvent) {
            this.btnAdd = document.getElementById("btnCount");
            this.btnAdd.onclick = this.AddClickHandler.bind(this);

            this.addCB = _addCallBack;
        }

        private AddClickHandler() {
            this.addCB && this.addCB();
        }
    }

    class Left {
        public handleAdd() {
            const counter = document.getElementById('leftCount');
            counter.innerText = (parseInt(counter.innerText)+1).toString();
        }
    }

    class Right {
        public handleAdd() {
            const counter = document.getElementById('rightCount');
            counter.innerText = (parseInt(counter.innerText)+1).toString();
        }
    }

    class App {
        private toolBar: ToolBar;
        private leftCom: Left;
        private rightCom: Right;

        constructor() {
            this.leftCom = new Left();
            this.rightCom = new Right();
            this.toolBar = new ToolBar(this.onAddClick.bind(this));
        }

        private onAddClick() {
            this.leftCom.handleAdd();
            this.rightCom.handleAdd();
        }
    }
    const app = new App();
}
上一篇:angular国际化 / rxjs使用技巧


下一篇:使用rxjs和webRTC和vue实现视频流在本地网络上的传输Demo