diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000000..4322f1262f --- /dev/null +++ b/babel.config.js @@ -0,0 +1,35 @@ +module.exports = function (api) { + api.cache(true); + const presets = [ + [ + "@babel/preset-env", + { + targets: { + ie: 9, + chrome: 47, + }, + }, + ], + "@babel/preset-typescript", + ]; + const plugins = [ + [ + "@babel/plugin-proposal-decorators", + { + legacy: true, + }, + ], + "@babel/plugin-proposal-class-properties", + "@babel/plugin-transform-block-scoping", + ["@babel/plugin-transform-classes", { + loose: true, + }], + "@babel/plugin-transform-proto-to-assign", + // "@babel/plugin-transform-modules-commonjs", + ]; + + return { + presets, + plugins, + }; +}; diff --git a/types/global.d.ts b/types/global.d.ts new file mode 100644 index 0000000000..e73f3077e2 --- /dev/null +++ b/types/global.d.ts @@ -0,0 +1,13 @@ +interface Obj { + [key: string]: any; +} + +// declare let BI: Obj & import("../typescript/index")._BI; + +declare let BI: Obj; + +declare const Fix: Obj; + +declare interface String { + replaceAll(regx: string, callback: (str: string) => void): string; +} diff --git a/typescript/core/decorator/decorator.ts b/typescript/core/decorator/decorator.ts new file mode 100644 index 0000000000..63437a9f1e --- /dev/null +++ b/typescript/core/decorator/decorator.ts @@ -0,0 +1,61 @@ +export type Constructor = new(...args: any[]) => T; + +/** + * 注册widget + */ +export function shortcut() { + return function decorator(Target: Constructor & {xtype: string}): void { + BI.shortcut(Target.xtype, Target); + }; +} + +/** + * 注册model + */ +export function model() { + return function decorator}>(Target: U): void { + BI.model(Target.xtype, Target); + }; +} + +/** + * 类注册_store属性 + * @param Model model类 + * @param opts 额外条件 + */ +export function store(Model: Constructor & {xtype: string}, opts: { props?(this: unknown): { [key: string]: unknown } } = {}) { + return function classDecorator(constructor:U) { + return class extends constructor { + _store() { + const props = opts.props ? opts.props.apply(this) : undefined; + + return BI.Models.getModel(Model.xtype, props); + } + }; + }; +} + +/** + * Model基类 + */ +export class Model} = {}> extends Fix.Model { + // @ts-ignore this["computed"][key]为空 + model: Pick<{[key in keyof U["types"]]: U["types"][key]}, U["context"][number]> & {[key in keyof ReturnType]: ReturnType[key]} & {[key in keyof this["computed"]]: ReturnType}; + + store: this["actions"]; + + state(): {[key: string]: unknown} | {} { + return {}; + } + + context: U["context"]; + + actions:{[key: string]: (...args: any[]) => any}; + + childContext: ReadonlyArray)>; + + // @ts-ignore this["computed"][key]为空 + TYPE: Pick<{[key in keyof this["computed"]]: ReturnType} & {[key in keyof ReturnType]: ReturnType[key]}, this["childContext"][number]>; + + computed: {[key: string]: () => unknown} | {}; +} diff --git a/webpack/dirs.js b/webpack/dirs.js new file mode 100644 index 0000000000..9c91758031 --- /dev/null +++ b/webpack/dirs.js @@ -0,0 +1,8 @@ +const path = require("path"); +module.exports = { + DEST: path.resolve(__dirname, "../dist"), + NODE_MODULES: path.resolve(__dirname, "../node_modules"), + PRIVATE: path.resolve(__dirname, "../private"), + BABEL_CONFIG: path.resolve(__dirname, "../babel.config.js"), + TYPESCRIPT: path.resolve(__dirname, "../typescript"), +}; diff --git a/webpack/webpack.common.js b/webpack/webpack.common.js new file mode 100644 index 0000000000..e487308cbc --- /dev/null +++ b/webpack/webpack.common.js @@ -0,0 +1,59 @@ +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const autoprefixer = require("autoprefixer"); + +const dirs = require("./dirs"); + +module.exports = { + entry: { + fineui: [ + "./typescript/index.ts", + ], + }, + resolve: { + mainFields: ["module", "main"], + extensions: [".js", ".ts"], + }, + module: { + rules: [ + { + test: /\.(js|ts)$/, + include: [dirs.NODE_MODULES, dirs.PRIVATE, dirs.TYPESCRIPT], + use: [{ + loader: "babel-loader", + options: { + configFile: dirs.BABEL_CONFIG, + }, + }, { + loader: "source-map-loader", + options: { + enforce: "pre", + }, + }], + }, + { + test: /\.(css|less)$/, + use: [ + MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + url: false, + }, + }, + { + loader: "postcss-loader", + options: { + plugins: [autoprefixer], + }, + }, + { + loader: "less-loader", + options: { + relativeUrls: false, + }, + }, + ], + }, + ], + }, +}; diff --git a/webpack/webpack.dev.js b/webpack/webpack.dev.js new file mode 100644 index 0000000000..1baca5684f --- /dev/null +++ b/webpack/webpack.dev.js @@ -0,0 +1,50 @@ +const merge = require("webpack-merge"); +const path = require("path"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); +const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); + +const dirs = require("./dirs"); + +const common = require("./webpack.common.js"); + +module.exports = merge(common, { + devtool: "eval-source-map", + output: { + path: dirs.DEST, + filename: "[name].[contenthash].js", + }, + devServer: { + contentBase: path.join(__dirname, ".."), + port: 9001, + liveReload: true, + }, + plugins: [ + new MiniCssExtractPlugin({ + path: dirs.DEST, + filename: "fineui.[contenthash].css", + }), + new HtmlWebpackPlugin({ + template: path.resolve(__dirname, "../index.html"), + chunks: ["fineui"], + chunksSortMode: "manual", + }), + new ForkTsCheckerWebpackPlugin({ + watch: ["./typescript"], + }), + new OptimizeCssAssetsPlugin({ + assetNameRegExp: /\.css$/g, + cssProcessor: require("cssnano"), + cssProcessorPluginOptions: { + preset: ["default", { + discardComments: { + removeAll: true, + }, + normalizeUnicode: false, + }], + }, + canPrint: true, + }), + ], +}); diff --git a/webpack/webpack.prod.js b/webpack/webpack.prod.js new file mode 100644 index 0000000000..380b0f29c8 --- /dev/null +++ b/webpack/webpack.prod.js @@ -0,0 +1,72 @@ +const webpack = require("webpack"); +const merge = require("webpack-merge"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin"); +const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); + +const dirs = require("./dirs"); + +const common = require("./webpack.common.js"); + +module.exports = merge.smart(common, { + mode: "production", + + devtool: "hidden-source-map", + + output: { + path: dirs.DEST, + filename: "webpack", + }, + + plugins: [ + new MiniCssExtractPlugin({ + path: dirs.DEST, + filename: "plugin.jsondata.es5.css", + }), + new UglifyJsPlugin({ + test: /\.js(\?.*)?$/i, + parallel: 16, + sourceMap: true, + uglifyOptions: { + output: { + comments: false, + }, + }, + }), + new webpack.BannerPlugin({ + banner: `time: ${new Date().toLocaleString()}`, + }), + new ForkTsCheckerWebpackPlugin({ + }), + new OptimizeCssAssetsPlugin({ + assetNameRegExp: /\.css$/g, + cssProcessor: require("cssnano"), + cssProcessorPluginOptions: { + preset: ["default", { + discardComments: { + removeAll: true, + }, + normalizeUnicode: false, + }], + }, + canPrint: true, + }), + ], + + module: { + rules: [ + { + test: /\.(css|less)$/, + use: [ + { + loader: "postcss-loader", + options: { + plugins: [], + }, + }, + ], + }, + ], + }, +});