amos-build
descr
- supoport webpack@1: 小于 v1.2.68
- supoport webpack@2+: 大于 v2.0.0
- update babel@7.x since v3.1.0
amos-build@5.0.3
以上版本,去掉默认module.exports
支持,混用export
和export default
的模块会存在部分bug,需要自行修改
node-sass install wizard
基于 webpack 的构建封装.
特性
- 基于 webpack 实现
- 支持通过
webpack.config.js
进行扩展 webpack 的配置项 - 支持导出
amosConfig.js、dll/*
进行自定义扩充 - @deprecated 支持 stage-0, es2015, react,sass 和 less
- 支持 env
- 支持dll,通过与amos-dll配合,快速进行构建,注意配置context为build目录
- 支持发布模式,并进行zip压缩,通过
.amosrun.config.js
进行自定义配置 - 支持 hash 模式的构建, 并生成映射表
map.json
- 插件:
plugins/*
,集成SimpleProgress、WebpackMd5Hash、AddAssetHtmlPlugin等 - 添加 worker-loader 支持 @since v2.0.19
安装
npm i amos-build --save--dev
使用
amos-build [options]
命令行参数
$ amos-build -h
Usage: amos-build [options]
Options:
-h, --help output usage information
-v, --version output the version number
-o, --output-path <path> output path
-w, --watch [delay] watch file changes and rebuild
--hash build with hash and output map.json
--publicPath <publicPath> webpack publicPath
--devtool <devtool> sourcemap generate method, default is null
--config <path> custom config path, default is webpack.config.js
--no-compress build without compress
配置扩展
如果需要对内置的 webpack 配置进行修改, 可在项目根目录新建 webpack.config.js
进行扩展.
让 webpack.config.js
输出 Function
, 比如:
const path = require("path");
module.exports = function(webpackConfig) {
webpackConfig.output.path = path.join(__dirname, './public');
return webpackConfig;
};
参数:
-
webpackConfig
-- 默认配置, 修改后返回新的配置
详细内容:amos-build 基本使用
-
amos-run
-
common: scss/js src/** to lib,retain original scss
-
singlejs: build for react components js,width js/jsx, output lib
-
assetscss: build for assetscss,with less、sass/scss
-
amosantd: for amos-antd
-
amosantdCustom: build for amosantdCustom,with less、css js/jsx
-
static
-
assets2dist
-
scss
-
amoscoreJs: build for amos-core js,
width js/jsx, output min.js/.css
-
amoscore: for amos-core,按顺序执行 ['scss', 'static', 'assets2dist', 'amoscoreJs']。
-
amoscoreCustom: for amos-core
-
security: for amos-security,
build for amos-security,width scss/sass js/jsx, output min.js/.css
-
amd: for amd,only copy file to
released
-
themes: build all themes. you should copy this files to prod dir
-
themes-watch: build themes and watch themes dir
-
commonExtra: 公共Extra,将额外文件打包进released下
-
src-static-all: static all
-
third-js: third js, 将根目录下
third、extra、plugin、plugins
文件夹之下的所有js、jsx拷贝至 lib 目录下,保留文件目录结构 -
released: for all released, copy
dist、src/assets/**、extra/**、browser/**、*.html、amos.config.js、favicon.ico
to released -
dllreleased: for all dllreleased dev
-
dllreleased-test: for all dllreleased test
-
dllreleased-pre: for all dllreleased pre
-
dllreleased-prod: for all dllreleased prod
-
extraReleased: for all extraReleased released
-
extraReleased-prod: for all extraReleased released
-
extraReleased-test: for all extraReleased released
-
extraReleased-pre: for all extraReleased released
-
extraReleased-dev: for all extraReleased released
-
released2server: for all released and copy to remote server
-
dorobots: create robots
-
released2zip: zip released
-
-
amos-auto
-
amd: for amd,only copy file to
released
-
released: for all released
-
dllreleased: for all dllreleased
-
released2server: for all released and copy to remote server
-
released2zip: zip released
-
-
ab-tools
-
webpack: entry is
src/*.js
-
build: build
src/**/*.js、src/**/*.scss
, with react -
ab-babel:
src/**/*.js
non react -
ab-js:
src/**/*.js
non babel
-
-
amosConfig
for amos team
-
commonConfig
common webpack config
-
simpleConfig
build js with webpack
-
docitConfig
same as simpleConfig, and add parse md doc loader
-
dist
can make your single components with one bundle, example
amos-core/amos-antd
-
extra config
.amosrun.config.js
such as
module.exports = { // 指定zip文件名称 zip: 'released.rar', // default // 自定义配置 zip v5.0.5 版本新增 zip: { prefix: 'released', // 前缀,默认 released format: 'rar', // 文件格式,默认 rar,可选 zip date: true // 使用 date 作为后缀, false、true、datefmt [YYYYmmdd、YYYY、mmdd、HH:mm:SS] 等 年Y 月m 日d 时H 分M秒S }, // 同级目录静态文件的拷贝 默认: ['*.html', 'amos.config.js', 'favicon.ico'] extra: ['loadBMapLib.js', 'defaultSetting.js', '*.html', 'amos.config.js', 'favicon.ico'] };
simpleConfig/docitConfig/polyfillConfig
usage
- simpleConfig
/**
* webpack 打包配置文件
* @author ilex
*/
const simpleConfig = require('amos-build/lib/simpleConfig');
// ------------------------------------------------------
// 添加webpack加载别名,用于导包重定向,优化打包以及代码
// 此处需要自己进行定义
// 👻可修改
// ------------------------------------------------------
const alias = {
_MOCK: __dirname + '/src/_mock'
};
// ------------------------------------
// 入口点
// ------------------------------------
const entry = {
app: './src/entry/index.js'
};
const config = {
tpl: './tpl.html',
toFile: 'index.html',
// 设置自定义的网站 ico,默认为 amos.ico, 设置为 null 则不设置 ico
favicon: './my.ico',
entry: entry,
port: 3000,
useHot: true,
// 启用 worker `your.worker.js`,独立打包worker
enableWorker: true,
alias: alias,
sourceMap: true,
// 设置忽略压缩,默认在 prod 模式下,会自动加载 ugly 插件,该参数设置为 true时,将不再执行压缩
ignoreUgly: false,
excludeUgly: [/common\.js/, /app\.\w+\.js/], // 注意,excludeUgly 代表的是编译后生成的js文件
// Boolean|null|String, null|false|true。
// 设置为 null 则不启用 cache。
// 设置为 false 则采用系统 temp 路径。C:\\Users\\SmartRay\\AppData\\Local\\Temp\\.babel-cache
// 设置为 true 则采用当前项目目录。 -> node_modules/.cache/...
// 设置为 string 则在temp目录下新建目录。 '.cache' -> C:\\Users\\SmartRay\\AppData\\Local\\Temp\\.cache
cache: false
};
// 如果需要将指定的的 node_modules 下的包不进行 Ugly 处理,可以如下设置
// 以下设置,将会把 指定的 vender 包,打进 common.js 中
/*
const entry = {
app: './src/entry/index.js'
vender: ['react', 'react-dom', ...]
};
const config = {
...
excludeUgly: [/common\.js/, /vender\.\w+\.js/], // 注意,excludeUgly 代表的是编译后生成的js文件
};
*/
const defaultConfig = simpleConfig(config);
defaultConfig.name = 'amos-init';
module.exports = defaultConfig;
- docitConfig
同上,修改为
const docitConfig = require('amos-build/lib/docitConfig');
- polyfillConfig
同上,修改为
const polyfillConfig = require('amos-build/lib/polyfillConfig');
or const polyfillConfig = require('amos-build/lib/polyfillConfig/index.js');
- umdConfig
生成 umd
模式的模块。支持传入 cssModules
用于设置 css-loader
的 modules
属性。
webpack.config.js
const HtmlWebpackPlugin = require('amos-build/lib/plugins/HtmlWebpackPlugin');
const HtmlInlineCodePlugin = require('html-inline-code-plugin');
const resolveCwd = require('amos-build/lib/tools/resolveCwd');
const umdConfig = require('amos-build/lib/umdConfig');
const ENV = require('amos-build/lib/tools/__ENV__');
const alias = {
};
const entry = {
demo: './example/entry.umd.js'
};
const sourceMap = ENV === 'production' ? false : true
const config = {
entry,
alias,
// 仅 umdConfig 支持,表现为 output.pasth
outputPath: resolveCwd('docsite'), // 默认 为 dist 目录,注意 绝对路径
// 仅 umdConfig 支持,表现为 output.filename
filename: 'mydemo.js', // '[name].js'
library: 'mydemo',
libraryTarget: 'umd',
// 开启 css modules
// cssModules: true,
sourceMap
};
const defaultConfig = umdConfig(config);
if (ENV === 'development'){
defaultConfig.plugins.push(
// index tpl
new HtmlWebpackPlugin({
filename: 'index.html',
template: './tpl.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: false,
removeAttributeQuotes: false
},
chunksSortMode: 'dependency'
}),
new HtmlInlineCodePlugin({
inject: 'body',
begin: false,
tag: 'script',
code: `
console.log(mydemo);
var createUI = window.mydemo;
createUI();
`
})
);
}
module.exports = defaultConfig;
entry.umd.js
import React from 'react';
import { render } from 'react-dom';
import App from './App';
import './index.scss';
export default function createUI({ container = 'app' } = {}) {
render(<App />, document.getElementById(container));
}
umd 模式新增 code-split since 5.0.1
使用默认 scripts.json
动态加入umd chunk 脚本
// 界面直接加载
fetch('/scripts.json').then(function(res){
return res.json();
}).then(function(data){
data.head.scripts.forEach(function(js){
// document.write(js);
});
data.head.urls.forEach(function(url){
var scri = document.createElement('script');
scri.src = url;
document.body.appendChild(scri);
});
data.head.tags.forEach(function(tag){
var t = document.createElement(tag.tagName);
if (tagName === 'script'){
t.src = tag.attributes.src;
}
document.body.appendChild(t);
});
data.body.scripts.forEach(function(js){
document.write(js);
});
});
// 通过代码引入
import scripts from './scripts.json';
- cjsLibConfig
默认启用使用 NodeModuleExternals
插件,生成 externals 配置。
同上,修改为
const cjsLibConfig = require('amos-build/lib/cjsLibConfig');
const cjsLibConfig = require('amos-build/lib/cjsLibConfig');
const config = {
external
};
设置 whitelist
将 node_modules
中的 required assets (i.e css files) 加入。
nodeExternals({
// load non-javascript files with extensions, presumably via loaders
whitelist: [/\.(?!(?:jsx?|json)$).{1,5}$/i],
})
plugins
ProgressWithMsg
options
property | type | description |
---|---|---|
messageTemplate | string | A template of progress and message shown while bundling modules. You can also use node-progress token. :msg shows current message of webpack ProgressPlugin. |
progressOptions | object | node-progress options to draw progress bar. defaults are shown below. |
import ProgressWithMsg from 'amos-build/lib/plugins/ProgressWithMsg';
// basic use
const webpackConfig = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'bundle.js'
},
plugins: [
new SimpleProgressPlugin()
]
};
// options
-- defaults
{
messageTemplate: [':bar', chalk.green(':percent'), ':msg'].join(' ')
progressOptions: {
complete: chalk.bgGreen(' '),
incomplete: chalk.bgWhite(' '),
width: 40,
total: 100,
clear: false
}
}
use dll
生成dll依赖
生成dll
webpack.dll.js
配置, 默认生成为Amoslib
const generateDll = require('amos-build/lib/dll/generateDll');
const path = require('path');
const config = {
amosLib: ['react', 'react-dom'],
// webpack.output.path dll文件生成目录
outputPath: 'dll',
// webpack.output.filename
fileName: '[name].js',
manifestPath: path.resolve(__dirname, 'dll/manifest.json'),
sourceMap: true;
};
module.exports = generateDll(config);
使用 dll
dll config (采用 amos-dll为例),注意目录为
根目录/build/amosbuildConf
, 由于amos-dll
执行时context
为build
目录
//-----------------------------------------------------------
// notice: do not modify this file content except entry/alias
// you can modify some config such as
// `showProgress/tpl/productionSourceMap/productionGzip`
// and so on
//-----------------------------------------------------------
const path = require('path');
const distPath = path.resolve(__dirname, '..', 'dist');
// const projectRoot = path.resolve(__dirname, '../');
const assetsPath = function(_path) {
return path.posix.join('static', _path);
};
// ------------------------------------
// 入口点
// 👻 可修改
// ------------------------------------
const entry = {
// app: './src/entry/index.js'
app: './src/entry/demo.js'
};
// ------------------------------------
// 添加webpack加载别名,用于导包重定向,优化打包以及代码
// 此处需要自己进行定义
// 👻可修改
// ------------------------------------
const alias = {
// MODEL: projectRoot + '/src/model',
// UTILS: projectRoot + '/src/utils',
// CONSTS: projectRoot + '/src/consts'
};
//-----------------------------------------------------------
// 👻 可修改,除非你知道该怎么修改
///-----------------------------------------------------------
module.exports = {
webpackConf: {
name: 'fireiot',
entry: entry,
alias: alias
},
showProgress: true,
context: __dirname,
tpl: 'tpl.html',
extractTextPath: assetsPath('css/[name].css?v=[contenthash:8]'),
visualizer: path.resolve(distPath, 'visualizer.html'),
prod: {
dll: {
fileName: './node_modules/amos-dll/common/prod/Amoslib.js', // 完整路径
manifest: 'amos-dll/common/prod/manifest.json',
outputPath: assetsPath('common/js'), // 生成目录
publicPath: '/static/common/js' // 注入地址
},
toFile: path.resolve(distPath, 'index.html'),
assetsRoot: distPath,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: false,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
output: {
path: distPath,
filename: assetsPath('js/[name].js?v=[chunkhash:8]'),
chunkFilename: assetsPath('js/chunk.[id].js?v=[chunkhash:8]')
}
},
dev: {
dll: {
fileName: './node_modules/amos-dll/common/dev/Amoslib.js', // 完整路径
manifest: 'amos-dll/common/dev/manifest.json',
outputPath: assetsPath('common/js'), // 生成目录
publicPath: '/static/common/js' // 注入地址
},
toFile: 'index.html',
port: 9000,
assetsRoot: distPath,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
staticPath: '/common',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false,
output: {
path: distPath,
filename: assetsPath('js/[name].js'),
chunkFilename: assetsPath('js/chunk.[id].js')
}
},
test: {
dll: {
fileName: './node_modules/amos-dll/common/prod/Amoslib.js', // 完整路径
// fileName: require.resolve('amos-dll/common/prod/Amoslib.js'),
manifest: 'amos-dll/common/prod/manifest.json',
outputPath: assetsPath('common/js'), // 生成目录
publicPath: '/static/common/js' // 注入地址
},
index: path.resolve(distPath, 'index.html'),
assetsRoot: distPath,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css']
}
};
webpack.config.dll.prod.js (根目录)
const dllConfig = require('amos-build/lib/dll/prod');
const config = require('./build/amosbuildConf');
module.exports = dllConfig(config);
react-native to web
useage
- install
安装 react-native-web
$ npm install --save-dev react-native-web
- setup webpack.config.js
// webpack.config.js
const rn2webConfig = require('amos-build/lib/reactNativeToWeb');
module.exports = rn2webConfig();
// custom options
const options = {
port: 3003,
alias: alias,
sourceMap: true
};
module.exports = rn2webConfig(options);
- add index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>ilex.h</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="react-root"></div>
<script src="/dist/index.web.js"></script>
</body>
</html>
配置第三方模块按需加载 babel 加载时
since@3.1.2 版本及之后版本支持。仅支持:umdConfig、simpleConfig、cjsLibConfig
三种模式
const afModuleMapping = require('amos-framework/lib/moduleMapping');
const adModuleMapping = require('amos-antd/lib/moduleMapping');
const config = {
entry,
outputPath: resolveApp('docsite'),
filename: '[name].js',
library: 'BabelDemo',
libraryTarget: 'umd',
// 配置自定义 babel 插件
babelPlugin: [
[
require.resolve('ray-pack-toolkit/lib/babel/SplitImportPlugin'),
{
libraryName: ['amos-framework', 'amos-antd'],
customMapping: {
// 特殊处理
'amos-framework': afModuleMapping,
'amos-antd': adModuleMapping
}
}
]
],
sourceMap: false
};
注意事项
simpleConfig/docitConfig/polyfillConfig
等,均设置 publicPath
为服务器根路径,如果需要使用相对路径,或其他路径,可以自定义 output 或者,删掉改属性。主要表现在,webpack 打包时,注入的文件路径。
<script type="text/javascript" src="/common.js">
如果去掉 publicPath
,则最终的 html 如下:
<script type="text/javascript" src="common.js">
实现方式:
var docitConfig = require('amos-build/lib/docitConfig');
// ... 配置信息
var defaultConfig = docitConfig(config);
// 删除 publicPath
delete defaultConfig.output.publicPath;
// 修改 publicPath
defaultConfig.output.publicPath = '.'; // <script type="text/javascript" src="./common.js">
常见错误剖析
在开发模式下,开启split,部分chunk file hash值并未改变,但是内容却变了
剖析:该问题,是由webpack进行模块分割时,经常会出现的bug
解决:
const webpack = require('webpack');
// 方式一:将系统中默认采用 id 命名方式,改为 NamedModulesPlugin
defaultConfig.plugins.push(
// new webpack.HashedModuleIdsPlugin();
// 非必须
// new webpack.NamedModulesPlugin();
new webpack.NamedChunksPlugin((chunk) => {
if (chunk.name) {
return chunk.name;
}
return chunk.mapModules(m => m.id).join('_');
}),
);
// 方式二:采用 hash 方式, 不推荐,因为每次都会更改 hash 值。原始采用的是 chunkhash
defaultConfig.output.filename = '[name].[hash].js';
defaultConfig.output.chunkFilename = 'chunk/[name].[hash].js';
在 3.0.12 及其之后版本,新增 useHash
来默认启用 hash 的方式创建文件名,仅在 production
模式下起效。
const simpleConfig = require('amos-build/lib/simpleConfig');
const config = {
...
useHash: true
};
const defaultConfig = simpleConfig(config);
externals 说明
use a regex in the Webpack config
Webpack allows inserting regex in the externals array, to capture non-relative modules:
{
externals: [
// Every non-relative module is external
// abc -> require("abc")
/^[a-z\-0-9]+$/
]
}
// 自定义
{
externals: [
function(context, request, callback) {
if (/^(amos-|ray-)/i.test(request)){
// return callback(null, 'umd ' + request);
return callback(null, 'commonjs ' + request);
}
callback();
},
/^(react|react-dom|prop-types|dt2react|classnames|moment)$/i,
/^(amos-|ray-)/i,
]
}
这种方式,会强制将所有的 non-relative requires 剥离,如果使用了
alias
配置,将不会进行bundled
。
采用 NodeMoudleExternals
实现仅仅剥离 node_modules
中的模块。
webpack 5.x 之后版本
手动添加 node 依赖支持:
mqtt-packet/writeToStream.js
依赖 safe-buffer 和 process-nextick-args
,将 buffer 和 process
设置为 amos-mqtt 的强依赖。
-
mqtt (readable-stream)
-
jszip/lib/readable-stream-browser.js
(stream) -
Buffer:
buffer
mqttamos-mqtt
中将其声明为强依赖 -
process:
process/browser
mqttamos-mqtt
中将其声明为强依赖 -
stream:
stream-browserify
jszipamos-viz
中将其声明为强依赖
v5.0.3
及之前版本,多次通过@import
引入重复的 css 或者 scss 将会导致最终打包生成多份样式。v5.0.4
解决重复引入样式问题,及工程中无.stylelintrc.json
文件问题。
新增 zipConfig
since 5.0.3 版本之后,新增 zipConfig。
支持 simpleConfig、umdConfig、docitConfig、cjsLibConfig、themeConfig、MFConfig
const config = {
zipConfig: {
// 复制
copy: [
{ source: 'dist/**', destination: 'released' },
{ source: 'amos.config.js', destination: 'released/amos.config.js' },
{ source: 'src/assets/**', destination: 'released/src/assets' }
],
// 删除文件夹或者文件
delete: ['zip/**'],
// 创建文件夹
mkdir: ['zip/'],
// 压缩
// options 配置 https://www.archiverjs.com/archiver
archive: [
{ source: 'released/**', destination: 'zip/released.zip' },
{ source: 'amos.config.js', destination: 'zip/conf.zip' },
{ source: 'dist/robot.txt', destination: 'zip/robot.zip' },
{ source: 'dist/**', destination: 'zip/dist.zip', format: 'tar' },
// 开启gzip
{ source: 'dist/**', destination: 'zip/dist.zip', format: 'tar', options: {
gzip: true,
gzipOptions: {
level: 1,
},
globOptions: {
nomount: true,
}
} }
]
}
};
案例:
组态工程中,将sdkroot 目录进行打包,同时将 scripts.json
文件独立拷贝
注意,打包之前,需要手动先删除
external/morphic/
目录,可直接在组态 npm scripts 中新增"cleanSdk": "rimraf sdkroot external/morphic"
const config = {
...
zipConfig: {
copy: [
{ source: 'sdkroot/scripts.json', destination: 'external/morphic/scripts.json' }
],
archive: [
{ source: 'sdkroot', destination: 'external/morphic/sdk.zip' }
]
}
...
};
新增 gzip
since v5.1.1
版本之后,新增 gzip
配置项,可以在打包时开启 gzip 特性。
gzip
也可以直接使用 nginx
中的 gzip
特性,无需打包处理。
const config = {
...
gzip: true // 简单使用,采用默认 `test: /\.js(\?.*)?$/i`
gzip: {
test: /\.js(\?.*)?$/i,
include: /\/includes/,
exclude: /\/excludes/,
algorithm: "gzip",
compressionOptions: {
level: 9
},
threshold: 0,
minRatio: 0.8,
filename: '[path][base].gz',
deleteOriginalAssets: false
}
};
nginx 开启 gzip
#开启和关闭gzip模式
gzip on|off;
#gizp压缩起点,文件大于1k才进行压缩
gzip_min_length 1k;
# gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间
gzip_comp_level 5;
# 进行压缩的文件类型。
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript;
#nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
gzip_static on|off
# 是否在http header中添加Vary: Accept-Encoding,建议开启
gzip_vary on;
# 设置压缩所需要的缓冲区大小,以4k为单位,如果文件为7k则申请2*4k的缓冲区
gzip_buffers 2 4k;
# 设置gzip压缩针对的HTTP协议版本
gzip_http_version 1.1;
MFConfig
采用 ModuleFederation 模式,创建 config 配置脚本。MfConfig 是 simpleConfig 的产物扩展功能而来
新增配置参数: mfConfig、mfMode
const MFConfig = require('amos-build/lib/MFConfig');
const { getReactMf, getShared } = require('amos-build/lib/tools/pluginConfig');
const { dependencies: deps, devDependencies: devps } = require('./package.json');
// both 模式
const mfOption = {
name: 'amosasp',
// 默认 library,可以不传入
library: { type: 'var', name: 'amosasp' },
filename: 'remoteEntry.js',
remotes: __ENV__ === 'production' ? mfInfo.remotes.prod : mfInfo.remotes.dev,
exposes: {
'./amos-xxx': './src/xxx.js'
},
shared: {
...getReactMf(deps.react, deps['react-dom'])
}
};
// host 模式
const mfOption = {
remotes: __ENV__ === 'production' ? mfInfo.remotes.prod : mfInfo.remotes.dev,
shared: {
...getReactMf(deps.react, deps['react-dom'])
}
};
// remote 模式
const mfOption = {
name: 'amosaf',
// 默认 library,可以不传入
library: { type: 'var', name: 'amosaf' },
filename: 'remoteEntry.js',
exposes: {
'./amos-xxx': './src/xxx.js'
},
shared: {
...getReactMf(devps.react, devps['react-dom']),
...getShared([
// 'amos-tool', 'crispfit-ui', 'domtool', 'dt2react'
'amos-tool', 'dt2react'
], deps)
}
};
const config = {
...
mfConfig: mfOption,
mfMode: 'both', // remote、host
...,
replacer: {
pkgs: [],
rules: [
{ src: 'amos-xxx', dest: 'amosaf/amos-xxx' },
]
}
};
// 搭配 replacer 进行使用,可以编译时替换目录
umdConfig、cjsLibConfig
想直接使用 remotes 模块,采用如下方式即可:
const umdConfig = require('amos-build/lib/umdConfig');
const { getReactMf, getShared, invokeMFRemotes } = require('amos-build/lib/tools/pluginConfig');
const { dependencies: deps, devDependencies: devps } = require('./package.json');
// host 模式
const mfOption = {
remotes: __ENV__ === 'production' ? mfInfo.remotes.prod : mfInfo.remotes.dev,
shared: {
...getReactMf(deps.react, deps['react-dom'])
}
};
const config = {
...,
replacer: {
pkgs: [],
rules: [
{ src: 'amos-xxx', dest: 'amosaf/amos-xxx' },
]
}
};
const defaultConfig = umdConfig(config);
invokeMFRemotes(defaultConfig, mfOption);
module.exports = defaultConfig;
教程系列
项目中使用 .umdrc.js 配置文件
.umdrc.js
位于项目根目录
const { commonExternals } = require('amos-build/lib/tools/pluginConfig');
// 通过 commonExternals 快速创建 umdConfig
const umdConfig = commonExternals([
'react', 'react-dom', 'amos-react-router', 'prop-types', 'amos-antd', 'amos-framework', 'xgplayer', 'xgplayer-flv', 'xgplayer-hls', 'amos-designer',
// studio asp remote 需要
'base-r3d', 'amos-gojs'
]);
module.exports = {
// dir 和 list 用于从 pkg 中拷贝 mf 包
dir: 'website/umd_lib',
list: [
...umdConfig.list,
// codemirror、ace
{ pkg: 'amos-code-actuator', umd: 'dist' },
// tinymce quill
{ pkg: 'amos-richtext', umd: 'umd' },
// echarts all
{ pkg: 'amos-viz', umd: 'umd' }
],
externals: {
...umdConfig.externals,
'amos-code-actuator/lib/codemirror/umd': 'ActuatorCM',
// ace editor
'amos-code-actuator/lib/ace/umd': 'ActuatorACE',
'amos-viz/lib/echarts/umd': 'VizEcharts',
// rich text
'amos-richtext/lib/quill/umd': 'RichTextQuill',
'amos-richtext/lib/tinymce/umd': 'RichTextMCE'
},
scripts: {
// 注意,数组中,靠前的后加载
head: [
...umdConfig.scripts.head
],
body: [
...umdConfig.scripts.body,
"amos-code-actuator/codemirror.umd.js",
"amos-code-actuator/ace.umd.js",
"amos-viz/viz-echarts.umd.js",
"amos-richtext/tinymce.umd.js",
"amos-richtext/quill.umd.js",
]
},
// link 样式可以, 均放在 head
links: [
...umdConfig.links
]
};
根目录的 webpack.config.js
umd_lib
内容可采取线上模块,也可采用 amos-plugin --umd --umd-r
命令动态生成
/**
* webpack 打包配置文件
* @author ilex
*/
const MFConfig = require('amos-build/lib/MFConfig');
const { getRCConfigInfo, getOuterScripts, getDynamicTags } = require('amos-build/lib/tools/pluginConfig');
const HtmlInlineCodePlugin = require('html-inline-code-plugin');
const umdRc = getRCConfigInfo('umd', '');
const defaultConfig = MFConfig({ ... });
// 设置 外部脚本配置
defaultConfig.externals = umdRc.externals;
// prefix 可以填写线上已发布目录,如 `http://172.16.10.72/umd_lib/`,此时无需执行相关 umd copy
// 给 html 加入 externals 脚本
const headLibs = getOuterScripts(umdRc.scripts.head, {
inject: 'head',
prefix: '/umd_lib/'
});
const bodyLibs = getOuterScripts(umdRc.scripts.body, {
inject: 'body',
prefix: '/umd_lib/'
});
const headLinks = getDynamicTags(umdRc.links, {
inject: 'head',
prefix: '/umd_lib/'
});
defaultConfig.plugins.push(
new HtmlInlineCodePlugin([
...headLibs,
...bodyLibs,
...headLinks
])
);
BUGS
启用 ModuleFederationPlugin 时,babel-loader 设置 presets 存在的bug
Uncaught (in promise) Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react
[
resolve('@babel/preset-react'),
[
resolve('@babel/preset-env'),
{
// https://babeljs.io/docs/en/babel-preset-env#modules
// 设置为 false 将会保留 es 模块。将imports和exports让webpack去处理
modules: 'amd', // 该值仅当设置为 `amd umd auto false` 时,才能使用 ModuleFederationPlugin
targets: {
browsers: envBrowsers
}
}
]
];