From 086409456542db2c9a8e666ce51826efb948f1ff Mon Sep 17 00:00:00 2001 From: Meck Zhu Date: Sat, 23 May 2020 02:27:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E6=97=B6=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit close #983 --- docs/guide/advanced/plugin.md | 60 +- packages/remax-cli/src/API.ts | 10 + .../fixtures/runtime-plugin/expected/app.acss | 0 .../fixtures/runtime-plugin/expected/app.js | 96 + .../fixtures/runtime-plugin/expected/app.json | 5 + .../runtime-plugin/expected/pages/index.acss | 0 .../runtime-plugin/expected/pages/index.axml | 1909 ++++++++++ .../runtime-plugin/expected/pages/index.js | 63 + .../runtime-plugin/expected/pages/index.json | 3 + .../runtime-plugin/expected/remax-vendors.js | 3119 +++++++++++++++++ .../runtime-plugin/expected/runtime.js | 154 + .../fixtures/runtime-plugin/remax.config.js | 7 + .../fixtures/runtime-plugin/runtime.js | 8 + .../fixtures/runtime-plugin/src/app.config.js | 3 + .../fixtures/runtime-plugin/src/app.js | 7 + .../runtime-plugin/src/pages/index.js | 6 + .../__tests__/integration/helpers/build.ts | 3 +- .../integration/runtimePlugin.test.ts | 9 + .../src/build/webpack/config.mini.ts | 14 + packages/remax-cli/template/plugin.js.ejs | 8 + packages/remax-runtime/package.json | 1 + packages/remax-runtime/src/PluginDriver.ts | 30 + .../src/__mocks__/@remax/runtime-plugin.ts | 3 + .../src/__tests__/PluginDriver.test.ts | 41 + packages/remax-runtime/src/createAppConfig.ts | 3 +- .../remax-runtime/src/createPageConfig.ts | 3 +- packages/remax-runtime/src/index.ts | 1 + packages/remax-runtime/tsconfig.json | 6 +- packages/remax-runtime/typings/index.d.ts | 1 + packages/remax-types/src/index.ts | 5 + 30 files changed, 5569 insertions(+), 9 deletions(-) create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.acss create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.json create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.acss create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.axml create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.json create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/remax-vendors.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/runtime.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/remax.config.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/runtime.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/src/app.config.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/src/app.js create mode 100644 packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/src/pages/index.js create mode 100644 packages/remax-cli/src/__tests__/integration/runtimePlugin.test.ts create mode 100644 packages/remax-cli/template/plugin.js.ejs create mode 100644 packages/remax-runtime/src/PluginDriver.ts create mode 100644 packages/remax-runtime/src/__mocks__/@remax/runtime-plugin.ts create mode 100644 packages/remax-runtime/src/__tests__/PluginDriver.test.ts diff --git a/docs/guide/advanced/plugin.md b/docs/guide/advanced/plugin.md index 6135a2cb69..374381d068 100644 --- a/docs/guide/advanced/plugin.md +++ b/docs/guide/advanced/plugin.md @@ -31,13 +31,13 @@ module.exports = { ## 编写插件 -Remax 的插件是一个简单的方法,这个方法返回一个对象,对象中的 key 是 Remax 提供的 hook 名。通过这些 hook,可以改变 Remax 构建小程序时的行为。 +Remax 插件分为编译时插件和运行时插件,插件是一个 Object,Object 的 key 对应 Remax 提供的 hook 名。 还是以 `@remax/plugin-less` 为例,我们可以通过 `configWebpack` 这个 hook 新增一条处理 less 文件的规则。 ```js -// 第一个参数是插件的配置 -const lessPlugin = options => { +// 因为需要接受参数,所以这里用一个方法来返回插件。 +export default options => { return { configWebpack({ config, addCSSRule }) { addCSSRule({ @@ -49,8 +49,6 @@ const lessPlugin = options => { }, }; }; - -export default lessPlugin; ``` ## Hooks @@ -81,6 +79,58 @@ export default lessPlugin; } ``` +### registerRuntimePlugin + +注册运行时插件。 + +```js +{ + registerRuntimePlugin() { + return path.resolve(__dirname, './runtime.js'), + } +} +``` + +## 运行时 Hooks + +### onAppConfig + +修改 App 的配置。 + +```js +{ + onAppConfig(config) { + const onLaunch = config.onLaunch; + config.onLaunch = () => { + console.log('onLaunch'); + if (onLaunch) { + onLaunch(); + } + } + return config; + } +} +``` + +### onPageConfig + +修改 Page 的配置。 + +```js +{ + onPageConfig(config) { + const onLoad = config.onLoad; + config.onLoad = () => { + console.log('onLoad'); + if (onLoad) { + onLoad(); + } + } + return config; + } +} +``` + ## 官方插件库 [https://github.com/remaxjs/plugins](https://github.com/remaxjs/plugins) diff --git a/packages/remax-cli/src/API.ts b/packages/remax-cli/src/API.ts index 7bdf46a3a4..abe6abfba5 100644 --- a/packages/remax-cli/src/API.ts +++ b/packages/remax-cli/src/API.ts @@ -108,6 +108,16 @@ export default class API { }); } + getRuntimePluginFiles() { + return this.plugins + .map(plugin => { + if (typeof plugin.registerRuntimePlugin === 'function') { + return plugin.registerRuntimePlugin(); + } + }) + .filter(Boolean); + } + public registerAdapterPlugins(targetName: Platform, remaxConfig: Options) { this.adapter.target = targetName; this.adapter.name = targetName; diff --git a/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.acss b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.acss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.js b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.js new file mode 100644 index 0000000000..d423e38f4d --- /dev/null +++ b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.js @@ -0,0 +1,96 @@ +require('./runtime.js'); +require('./remax-vendors.js'); +(my["webpackJsonp"] = my["webpackJsonp"] || []).push([[1],[ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +module.exports = __webpack_require__(1); + + +/***/ }), +/* 1 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony import */ var _remax_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(14); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__); +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function () { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + + + + +var _App = /*#__PURE__*/function (_React$Component) { + _inherits(_App, _React$Component); + + var _super = _createSuper(_App); + + function _App() { + _classCallCheck(this, _App); + + return _super.apply(this, arguments); + } + + _createClass(_App, [{ + key: "render", + value: function render() { + return this.props.children; + } + }]); + + return _App; +}(react__WEBPACK_IMPORTED_MODULE_1__["Component"]); + +/* harmony default export */ __webpack_exports__["default"] = (App(Object(_remax_runtime__WEBPACK_IMPORTED_MODULE_0__["createAppConfig"])(_App))); + +/***/ }), +/* 2 */, +/* 3 */, +/* 4 */ +/***/ (function(module, exports) { + +module.exports = require("react-reconciler"); + +/***/ }), +/* 5 */, +/* 6 */ +/***/ (function(module, exports) { + +module.exports = require("scheduler"); + +/***/ }), +/* 7 */, +/* 8 */, +/* 9 */, +/* 10 */, +/* 11 */, +/* 12 */, +/* 13 */, +/* 14 */ +/***/ (function(module, exports) { + +module.exports = require("react"); + +/***/ }) +],[[0,0,2]]]); \ No newline at end of file diff --git a/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.json b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.json new file mode 100644 index 0000000000..f1ba5b614e --- /dev/null +++ b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/app.json @@ -0,0 +1,5 @@ +{ + "pages": [ + "pages/index" + ] +} \ No newline at end of file diff --git a/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.acss b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.acss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.axml b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.axml new file mode 100644 index 0000000000..88308fe2eb --- /dev/null +++ b/packages/remax-cli/src/__tests__/integration/fixtures/runtime-plugin/expected/pages/index.axml @@ -0,0 +1,1909 @@ +