## 前端组件动态链接库
目前公司组件库采用npm私有仓库管理，随着接入项目逐步增加，组件版本升级不及时，基础依赖库管理混乱的问题也十分突出，因此将组件库改版成线上动态链接库，实现组件的热更新，且重要基础依赖库统一管理。组件库fl-pro也会持续维护，最新版本和动态链接库内容保持一致；

## 组件库使用文档
<a href="./fl-pro.md">fl-pro组件库使用文档</a>

### 动态链接库原理说明
采用webopack5的新特性--module Federation，可以实现组件动态链接的功能，和npm仓库管理的主要区别在于：
<img src="https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X3BuZy9RUmlieWpld00xSUFqWXhmVUl2a1J6Q3dJcDczOU81eXhsQUNVeDNlZU1KdjJmRHd0bTY5cGJpYUtsRk9CdXRENzhwWDQzRUxqVEdiMWliMzNlYlVBODBkZy82NDA?x-oss-process=image/format,png">

每一个项目都可以是组件的提供者和消费者，而组件是编译好的代码，作为独立单元开放出去，应用可以实现npm中心化的集中管理，当提供者的组件更新后，消费者的项目不用做任何更新就能获取最新代码，一切都是实时的；

### 项目改造说明

#### 1.依赖库升级
webpack升级版本>=5.10.0；

html-webpack-plugin升级版本>=4.5.0或者安装html-webpack-plugin@5.0.0-alpha.15版本，如果版本<5，编译时会有DeprecationWarning，但没有影响；安装@5.0.0-alpha.15就不会有DeprecationWarning；

mini-css-extract-plugin升级版本>=1.3.2；

copy-webpack-plugin版本>=6.4.0；

*说明：其他依赖项不用改动；

#### 2.wepack配置项修改
2.1） hash配置字段调整
webpack5中，废弃了hash字段的配置，转而改成fullhash，因此webpack配置文件中的hash需要统一改成fullhash，如下：

修改前：`'[name]-[hash:10].[ext]'`

修改后：`'[name]-[fullhash:10].[ext]'`

此外，contenthash字段没有改变，因此不用修改；

2.2）新增ModuleFederationPlugin配置
```
...
const { ModuleFederationPlugin } = require("webpack").container;
const deps = require("./package.json").dependencies; // 获取项目依赖项
...

plugins: [
    ...
    new ModuleFederationPlugin({
      name: "app", // 你的项目名，便于别人引用，可自定以修改
      remotes: {
        dynamic_modules: "dynamic_modules@//10.100.10.80:10000/remoteEntry.js", // 组件动态库入口文件
      },
      shared: {
        ...deps,
        react: {
          singleton: true,
        },
        "react-dom": {
          singleton: true,
        },
      },
    }),
    ...
]
```

2.3）dll配置删除

删除index.ejs模板文件中的xx.dll.js文件
```
<!-- <script type="text/javascript" src="/resources/js/base.dll.js?v=<%= htmlWebpackPlugin.options.version %>"></script>
    <script type="text/javascript" src="/resources/js/vender.dll.js?v=<%= htmlWebpackPlugin.options.version %>"></script> -->
```
webpack.common.js文件删除dll引用
```
// const manifestBaseDll = require('./src/static/js/base-manifest.json');
// const manifestVenderDll = require('./src/static/js/vender-manifest.json');

// new webpack.DllReferencePlugin({
    //   context: __dirname,
    //   manifest: manifestBaseDll,
// }),
// new webpack.DllReferencePlugin({
    //   context: __dirname,
    //   manifest: manifestVenderDll,
// }),
```
说明：上面注释的代码可以直接删除；

2.4）splitChunks配置删除name属性
```
splitChunks: {
    chunks: 'all',
    minChunks: 2,
    // name: true, // name属性需要删除，否则项目启动报错
    maxInitialRequests: 4,
    ...
}
```

2.5）copy-webpack-plugin配置调整，添加patterns结构
```
修改前：
new CopyPlugin([{
    	context: __dirname,
        from: join(__dirname, 'src/configs/configs.js'),
        to: join(__dirname, 'dist/resources/js'),
    }, {
        from: 'src/static/js/*.js',
        to: join(__dirname, 'dist/resources/js'),
        flatten: true,
    },
]),
-----------------------------------------
修改后：
new CopyPlugin({
    patterns: [{
          	context: __dirname,
          	from: join(__dirname, 'src/configs/configs.js'),
          	to: join(__dirname, 'dist/resources/js'),
        }, {
            from: 'src/static/js/*.js',
            to: join(__dirname, 'dist/resources/js'),
            flatten: true,
    	},
	]
}),
```
#### 3.公司组件引入调整
3.1）在项目入口文件index.js同一级目录下新增bootstrap.js文件，内容为index.js的文件，可直接将index.js内容拷贝过去；
3.2）index.js项目入口文件调整为：`import('./bootstrap');`，只用包含这一句代码即可；

#### 4.项目入口文件调整
以运营测应用为例，商户测类推；
##### router.js
```
改造前：
// import RouteWithLayout from 'fl-pro/lib/RouteWithLayout';
// import FLayout from 'fl-pro/lib/FLayout';
----------------------------------------------------------
改造后：
import RouteWithLayout from 'dynamic_modules/RouteWithLayout';
import FLayout from 'dynamic_modules/FLayout';
```
##### bootstrap.js(原index.js文件)
```
改造前：
// import PublicLayout from 'fl-pro/lib/model/PublicLayout';
----------------------------------------------------------
改造后：
import PublicLayout from 'dynamic_modules/PublicLayout';
```

*说明：

1.所有动态链接组件引入方式都遵循'dynamic_modules/xxxx'格式；

2.其他组件也支持新的动态链接倒入，建议都采用这种方式，可以获得最新的组件支持；
