diff --git a/.eslintignore b/.eslintignore index 4c5db2a..e0f8cbd 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1,5 @@ node_modules -template +templates test temp dist diff --git a/README.md b/README.md index 433c8ae..8627b94 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,16 @@ Standard Tooling for Megalo Project Development | 包名 | 最新版本号 | 最后更新日期 | 包描述 | ------ | ------ | ------ | ------ | -| [@megalo/cli](./packages/@megalo/cli) | 1.0.0-alpha.1 | 2019/03/05 | 生成标准的megalo项目 | -| [@megalo/cli-service](./packages/@megalo/cli-service) | 1.0.0-alpha.10 | 2019/03/18 | megalo项目的webpack零配置插件 +| [@megalo/cli](./packages/@megalo/cli) | 1.0.0-alpha.3 | 2019/03/29 | 生成标准的megalo项目 | +| [@megalo/cli-service](./packages/@megalo/cli-service) | 1.0.0-alpha.15 | 2019/03/29 | megalo项目的webpack零配置插件 | [@megalo/entry](./packages/@megalo/entry) | 0.1.2 | 2019/03/01 | 读取入口文件的webpack插件(未来可能废弃,交由megalo-aot处理) | -| [@megalo/babel-preset-app](./packages/@megalo/babel-preset-app) | 1.0.0-alpha.1 | 2019/03/04 | 包装脚手架babel相关的配置 | +| [@megalo/babel-preset-app](./packages/@megalo/babel-preset-app) | 1.0.0-alpha.3 | 2019/03/25 | 包装脚手架babel相关的配置 | ## 其他相关包 | 包名 | 最新版本号 | 最后更新日期 | 包描述 | ------ | ------ | ------ | ------ | | [@megalo/eslint-config-standard](https://github.com/megalojs/eslint-config-standard) | 1.0.0 | 2019/03/21 | eslint-config-standard for megalo project | +| [@megalo/eslint-config-typescript](https://github.com/megalojs/eslint-config-typescript) | 1.0.0-alpha.1 | 2019/03/25 | eslint-config-typescript for magolo-cli | > 注: alpha 为内部开发测试版本,请勿在生产环境中使用 diff --git a/example/project01/package.json b/example/project01/package.json index f612b5c..4363b9f 100755 --- a/example/project01/package.json +++ b/example/project01/package.json @@ -17,12 +17,13 @@ }, "license": "MIT", "devDependencies": { - "@megalo/babel-preset-app": "^1.0.0-alpha.1", - "@megalo/cli-service": "^1.0.0-alpha.8", - "@megalo/entry": "^0.1.2", - "@megalo/eslint-config-standard": "^1.0.0-alpha.1", + "@megalo/babel-preset-app": "latest", + "@megalo/cli-service": "latest", + "@megalo/entry": "latest", + "@megalo/eslint-config-standard": "latest", "@megalo/target": "0.5.7", "@megalo/template-compiler": "^0.8.0", + "eslint": "^5.8.0", "less": "^3.8.1", "less-loader": "^4.1.0" }, diff --git a/packages/@megalo/cli/template/.env.development b/example/project02/.env.development old mode 100755 new mode 100644 similarity index 100% rename from packages/@megalo/cli/template/.env.development rename to example/project02/.env.development diff --git a/packages/@megalo/cli/template/.env.production b/example/project02/.env.production old mode 100755 new mode 100644 similarity index 100% rename from packages/@megalo/cli/template/.env.production rename to example/project02/.env.production diff --git a/packages/@megalo/cli/template/eslintignore b/example/project02/.eslintignore similarity index 100% rename from packages/@megalo/cli/template/eslintignore rename to example/project02/.eslintignore diff --git a/example/project02/.eslintrc.js b/example/project02/.eslintrc.js new file mode 100644 index 0000000..a4f8498 --- /dev/null +++ b/example/project02/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + '@megalo/standard', + '@megalo/typescript' + ] +} diff --git a/packages/@megalo/cli/template/gitignore b/example/project02/.gitignore similarity index 100% rename from packages/@megalo/cli/template/gitignore rename to example/project02/.gitignore diff --git a/packages/@megalo/cli/template/README b/example/project02/README.md similarity index 74% rename from packages/@megalo/cli/template/README rename to example/project02/README.md index 3b1db89..c92d59e 100644 --- a/packages/@megalo/cli/template/README +++ b/example/project02/README.md @@ -1,12 +1,12 @@ -# <%- projectName %> +# ts ## 描述 -<%- description %> +a megalo project ## 作者 -<%- author %> <<%- email %>> +bigMeow ## 运行 diff --git a/example/project02/megalo.config.js b/example/project02/megalo.config.js new file mode 100644 index 0000000..b2ab27e --- /dev/null +++ b/example/project02/megalo.config.js @@ -0,0 +1,43 @@ +module.exports = { + // 构件生产模式时是否生成source map(仅在process.env.NODE_ENV === 'production' 时该选项生效) + productionSourceMap: true, + + // 开启eslint格式化代码 + lintOnSave: true, + + configureWebpack: config => { + // 你可以在这里粗放的修改webpack的配置并返回 + console.log('configureWebpack执行了') + return config + }, + chainWebpack: chainConfig => { + // 你可以在这里通过 https://github.com/neutrinojs/webpack-chain 来精细的修改webpack配置 + + + console.log('chainWebpack执行了') + }, + // 原生小程序组件存放目录,默认为src/native + // 如果你有多个平台的原生组件,你应当在此目录下再新建几个子文件夹,我们约定,子文件夹名和平台的名字一致: + // 微信小程序组件则命名为 'wechat',支付宝为'alipay', 百度为 'swan' + // 如果只有一个平台,则无需再新建子文件夹 + nativeDir: '/src/native', + + css: { + loaderOptions: { + css: { + // https://github.com/webpack-contrib/css-loader#options + }, + less: { + // https://github.com/webpack-contrib/less-loader + }, + sass: { + // https://github.com/webpack-contrib/sass-loader + }, + stylus: { + // https://github.com/shama/stylus-loader + }, + // https://github.com/megalojs/megalo-px2rpx-loader + px2rpx: false + } + } +} diff --git a/example/project02/package.json b/example/project02/package.json new file mode 100644 index 0000000..1814f02 --- /dev/null +++ b/example/project02/package.json @@ -0,0 +1,42 @@ +{ + "name": "ts", + "version": "1.0.0", + "description": "a megalo project", + "main": "index.js", + "private": true, + "scripts": { + "build:wechat": "megalo-cli-service build", + "build:alipay": "megalo-cli-service build --platform alipay", + "build:swan": "megalo-cli-service build --platform swan", + "dev:alipay": "megalo-cli-service serve --platform alipay", + "dev:swan": "megalo-cli-service serve --platform swan", + "dev:wechat": "megalo-cli-service serve", + "lint": "eslint --fix --ext .js,.vue,.ts src" + }, + "author": "bigMeow ", + "license": "ISC", + "babel": { + "presets": [ + "@megalo/app" + ] + }, + "devDependencies": { + "@megalo/babel-preset-app": "latest", + "@megalo/cli-service": "latest", + "@megalo/eslint-config-standard": "latest", + "@megalo/eslint-config-typescript": "latest", + "@megalo/target": "0.7.0", + "@megalo/template-compiler": "^0.9.1-0", + "@types/node": "^11.11.4", + "eslint": "^5.8.0", + "stylus": "^0.54.5", + "stylus-loader": "^3.0.2", + "typescript": "^3.3.4000", + "vue-property-decorator": "^7.3.0" + }, + "dependencies": { + "@megalo/vhtml-plugin": "^0.1.2", + "megalo": "^0.9.1-0", + "octoparse": "^0.3.2" + } +} diff --git a/example/project02/src/App.vue b/example/project02/src/App.vue new file mode 100644 index 0000000..fa837b2 --- /dev/null +++ b/example/project02/src/App.vue @@ -0,0 +1,43 @@ + diff --git a/example/project02/src/components/HelloWorld.vue b/example/project02/src/components/HelloWorld.vue new file mode 100644 index 0000000..f674b8c --- /dev/null +++ b/example/project02/src/components/HelloWorld.vue @@ -0,0 +1,23 @@ + + + + + + diff --git a/packages/@megalo/cli/template/src/index.js b/example/project02/src/index.js similarity index 57% rename from packages/@megalo/cli/template/src/index.js rename to example/project02/src/index.js index 4eeaf14..59376ca 100644 --- a/packages/@megalo/cli/template/src/index.js +++ b/example/project02/src/index.js @@ -1,9 +1,24 @@ import App from './App' import Vue from 'vue' +import { Component } from 'vue-property-decorator' import VHtmlPlugin from '@megalo/vhtml-plugin' Vue.use(VHtmlPlugin) +// https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html +Component.registerHooks([ + 'onLoad', // 监听页面加载 + 'onShow', // 监听页面显示 + 'onReady', // 监听页面初次渲染完成 + 'onHide', // 监听页面隐藏 + 'onUnload', // 监听页面卸载 + 'onPullDownRefresh', // 监听用户下拉动作 + 'onReachBottom', // 页面上拉触底事件的处理函数 + 'onShareAppMessage', // 用户点击右上角分享 + 'onPageScroll', // 页面滚动 + 'onTabItemTap' // 当前是 tab 页时, 点击 tab 时触发 +]) + const app = new Vue(App) app.$mount() @@ -36,7 +51,7 @@ export default { window: { backgroundTextStyle: 'light', navigationBarBackgroundColor: '#fff', - navigationBarTitleText: 'haha', + navigationBarTitleText: 'Typescript', navigationBarTextStyle: 'black' } } diff --git a/packages/@megalo/cli/template/src/native/tabbar/home.png b/example/project02/src/native/tabbar/home.png similarity index 100% rename from packages/@megalo/cli/template/src/native/tabbar/home.png rename to example/project02/src/native/tabbar/home.png diff --git a/packages/@megalo/cli/template/src/native/tabbar/home_on.png b/example/project02/src/native/tabbar/home_on.png similarity index 100% rename from packages/@megalo/cli/template/src/native/tabbar/home_on.png rename to example/project02/src/native/tabbar/home_on.png diff --git a/packages/@megalo/cli/template/src/native/tabbar/mine.png b/example/project02/src/native/tabbar/mine.png similarity index 100% rename from packages/@megalo/cli/template/src/native/tabbar/mine.png rename to example/project02/src/native/tabbar/mine.png diff --git a/packages/@megalo/cli/template/src/native/tabbar/mine_on.png b/example/project02/src/native/tabbar/mine_on.png similarity index 100% rename from packages/@megalo/cli/template/src/native/tabbar/mine_on.png rename to example/project02/src/native/tabbar/mine_on.png diff --git a/example/project02/src/pages/hello.vue b/example/project02/src/pages/hello.vue new file mode 100644 index 0000000..ce4ceff --- /dev/null +++ b/example/project02/src/pages/hello.vue @@ -0,0 +1,103 @@ + + + + + diff --git a/example/project02/src/pages/my/my.vue b/example/project02/src/pages/my/my.vue new file mode 100644 index 0000000..9fe5112 --- /dev/null +++ b/example/project02/src/pages/my/my.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/example/project02/src/shims-vue.d.ts b/example/project02/src/shims-vue.d.ts new file mode 100644 index 0000000..c7807a0 --- /dev/null +++ b/example/project02/src/shims-vue.d.ts @@ -0,0 +1,12 @@ +declare module '*.vue' { + import Vue from 'vue'; + export default Vue; +} + +declare module 'megalo/types/vue' { + interface Vue { + $mp: any + } +} + +declare function getApp() diff --git a/packages/@megalo/cli/template/src/static/imgs/megalo_logo.png b/example/project02/src/static/imgs/megalo_logo.png similarity index 100% rename from packages/@megalo/cli/template/src/static/imgs/megalo_logo.png rename to example/project02/src/static/imgs/megalo_logo.png diff --git a/example/project02/tsconfig.json b/example/project02/tsconfig.json new file mode 100644 index 0000000..b1052bd --- /dev/null +++ b/example/project02/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + // 与 Vue 的浏览器支持保持一致 + "target": "es5", + // 这可以对 `this` 上的数据属性进行更严格的推断 + "strict": true, + "sourceMap": true, + "isolatedModules": true, + // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake: + "module": "esnext", + "moduleResolution": "node", + "baseUrl": "./", + // "outDir": "./dist/", + "paths": { + "vue": [ + "node_modules/megalo" + ], + "@/*": [ + "src/*" + ] + }, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "noImplicitAny": false, + "skipLibCheck": true, + "strictPropertyInitialization": false, + "experimentalDecorators": true, + "esModuleInterop": true + }, + "include": [ + "./src/**/*" + ], + "exclude": [ + "node_modules" + ], + "typeAcquisition": { + "enable": true + } +} diff --git a/packages/@megalo/babel-preset-app/index.js b/packages/@megalo/babel-preset-app/index.js index 7a9f8f4..6134814 100644 --- a/packages/@megalo/babel-preset-app/index.js +++ b/packages/@megalo/babel-preset-app/index.js @@ -1,3 +1,6 @@ +const path = require('path') +const fs = require('fs') +const isUseTypescript = fs.existsSync(path.join(process.env.MEGALO_CLI_CONTEXT, 'tsconfig.json')) module.exports = function () { // TODO 根据platform,分别输出真对小程序和h5的配置 const presets = [ @@ -20,6 +23,20 @@ module.exports = function () { ] ] + if (isUseTypescript) { + // 暂时用ts-loader 来替换 + // presets.push(['@babel/preset-typescript', { allExtensions: true }]) + plugins.push( + [ + '@babel/plugin-proposal-decorators', + { 'legacy': true } + ], + ['@babel/plugin-proposal-class-properties', + { 'loose': true } + ] + ) + } + return { presets, plugins diff --git a/packages/@megalo/babel-preset-app/package.json b/packages/@megalo/babel-preset-app/package.json index b917be3..2c0eb4b 100644 --- a/packages/@megalo/babel-preset-app/package.json +++ b/packages/@megalo/babel-preset-app/package.json @@ -1,6 +1,6 @@ { "name": "@megalo/babel-preset-app", - "version": "1.0.0-alpha.1", + "version": "1.0.0-alpha.4", "description": "包装megalo工程中babel相关的配置", "main": "index.js", "dependencies": { @@ -8,6 +8,8 @@ "@babel/plugin-transform-runtime": "^7.3.4", "@babel/preset-env": "^7.3.4", "@babel/runtime": "^7.3.4", + "@babel/plugin-proposal-class-properties": "^7.3.4", + "@babel/plugin-proposal-decorators": "^7.3.4", "babel-loader": "^8.0.5" }, "publishConfig": { diff --git a/packages/@megalo/cli-service/README.md b/packages/@megalo/cli-service/README.md index 526adca..5396439 100644 --- a/packages/@megalo/cli-service/README.md +++ b/packages/@megalo/cli-service/README.md @@ -1,18 +1,22 @@ # @megalo/cli-service 1.x版本 :hammer_and_wrench: megalo的开箱即用webpack小程序脚手架配置,内置megalo生态的部分插件,并提供用户自定义配置的入口 + +完整文档地址: https://megalojs.org/#/cli/cli-service + ## 特性 - 零配置可用 - 可根据自己的需求修改webpack原始配置 - 内置了小程序项目常用的基础设施配置,满足基本需求 - 项目配置分离,零耦和,配置插件化 +- typescript 支持 ## 注意 老项目注意 >>> `@megalo/cli-service` 1.0.0版本的api于 0.x的版本不兼容,使用方式有差异,0.x版本的点击[这里 ](./0.x-version.md) ## 安装 -`@megalo/cli-service` 依赖 `@megalo/babel-preset-app` 、`@megalo/entry`、`@megalo/target` 、`@megalo/template-compiler` +`@megalo/cli-service` 依赖 `@megalo/babel-preset-app` 、`@megalo/target` 、`@megalo/template-compiler` ```bash -npm i @megalo/babel-preset-app @megalo/entry @megalo/target @megalo/template-compiler @megalo/cli-service -D +npm i @megalo/babel-preset-app @megalo/target @megalo/template-compiler @megalo/cli-service -D ``` ## 使用 @@ -98,13 +102,10 @@ module.exports = { - 编译、压缩、混淆等 ## 注意 -`@megalo/cli-service` 对项目目录结构有一定要求, 例如: -- `src` 目录下一定要有 `index.js` 文件,作为入口 +`@megalo/cli-service` 默认会读取 `src` 目录下的 `main.js` 、 `index.js` 、`main.ts` 、`index.ts` 其中之一并将其作为入口文件 ## [demo](../../../example/project01/) -## TODO -- typescript 支持 ## 更新记录 -- [1.0.0 ] 正式版发布 +- [1.0.0 ] alpha迭代中 diff --git a/packages/@megalo/cli-service/bin/index.js b/packages/@megalo/cli-service/bin/index.js index fc8584e..bed8dac 100755 --- a/packages/@megalo/cli-service/bin/index.js +++ b/packages/@megalo/cli-service/bin/index.js @@ -44,6 +44,7 @@ program .option('--platform ', 'set target platform ', /^(wechat|alipay|swan|tt|h5)$/i, 'wechat') .option('--config ', 'set customer webpack config path ', '') .option('--report', 'generate report.html to help analyze bundle content ', false) + .option('--report-json', 'generate report.json to help analyze bundle content ', false) .option('--fix', 'eslint auto fix on save ', false) .option('--debug', 'open the debug logger ', false) diff --git a/packages/@megalo/cli-service/lib/utils/util.js b/packages/@megalo/cli-service/lib/utils/util.js index a9c1e2b..f0058fb 100644 --- a/packages/@megalo/cli-service/lib/utils/util.js +++ b/packages/@megalo/cli-service/lib/utils/util.js @@ -55,16 +55,14 @@ exports.generateCssLoaders = (chainaConfig, projectOptions) => { config.tap(options => merge(options, projectOptions.css.loaderOptions['css'])) }) .end() - .use('px2rpx') - .loader('px2rpx-loader') - .options({ - rpxUnit: 0.5, - rpxPrecision: 6 - }) - .when(projectOptions.css.loaderOptions['px2rpx'], config => { - config.tap(options => merge(options, projectOptions.css.loaderOptions['px2rpx'])) - }) - .end() + .when(projectOptions.css.loaderOptions['px2rpx'], rule => { + rule.use('px2rpx') + .loader('px2rpx-loader') + .when(projectOptions.css.loaderOptions['px2rpx'], config => { + config.tap(options => merge(options, projectOptions.css.loaderOptions['px2rpx'])) + }) + .end() + }) .when(loaderName !== 'css', config => { config.use(loaderName) .loader(`${loaderName}-loader`) diff --git a/packages/@megalo/cli-service/lib/webpack/h5/serve.js b/packages/@megalo/cli-service/lib/webpack/h5/serve.js index a068532..a2b8dca 100644 --- a/packages/@megalo/cli-service/lib/webpack/h5/serve.js +++ b/packages/@megalo/cli-service/lib/webpack/h5/serve.js @@ -1,5 +1,5 @@ -const createBaseConfig = require('./webpack.base.config') - +const ChainableWebpackConfig = require('webpack-chain') +const { error } = require('@vue/cli-shared-utils') module.exports = (...args) => { error('暂不支持编译h5,敬请期待') diff --git a/packages/@megalo/cli-service/lib/webpack/index.js b/packages/@megalo/cli-service/lib/webpack/index.js index 23145be..a61ffc7 100644 --- a/packages/@megalo/cli-service/lib/webpack/index.js +++ b/packages/@megalo/cli-service/lib/webpack/index.js @@ -1,18 +1,15 @@ -const romoveFile = require('rimraf') +const fs = require('fs-extra') const path = require('path') const webpack = require('webpack') const { mergeUserConfig } = require('./mergeUserConfig') -module.exports = (...args) => { +module.exports = async (...args) => { const commandName = args[0] const projectOptions = args[2] const chainConfig = (process.env.PLATFORM === 'h5' ? require(`./h5/${commandName}`) : require(`./mp/${commandName}`))(...args) || {} const finalWebpackConfig = mergeUserConfig(chainConfig, projectOptions) - romoveFile(path.resolve(`dist-${process.env.PLATFORM}/*`), error => { - if (error) throw error - webpack(finalWebpackConfig, () => {}) - }) + await fs.remove(path.resolve(`dist-${process.env.PLATFORM}/*`)) + webpack(finalWebpackConfig, () => {}) } - diff --git a/packages/@megalo/cli-service/lib/webpack/mp/build.js b/packages/@megalo/cli-service/lib/webpack/mp/build.js index 790a5dd..3676448 100644 --- a/packages/@megalo/cli-service/lib/webpack/mp/build.js +++ b/packages/@megalo/cli-service/lib/webpack/mp/build.js @@ -2,9 +2,17 @@ const createBaseConfig = require('./webpack.base.config') module.exports = (commandName, commandOptions, projectOptions) => { const chainConfig = createBaseConfig(commandName, commandOptions, projectOptions) - chainConfig.when(projectOptions.report, config => { + chainConfig.when(commandOptions.report || commandOptions.reportJson, config => { config.plugin('bundle-analyzer') - .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) + .use( + require('webpack-bundle-analyzer').BundleAnalyzerPlugin, + [{ + analyzerMode: commandOptions.report ? 'static' : 'disabled', + reportFilename: `../${commandOptions.platform}-report.html`, + statsFilename: `../${commandOptions.platform}-report.json`, + generateStatsFile: !!commandOptions.reportJson + }] + ) }) return chainConfig } diff --git a/packages/@megalo/cli-service/lib/webpack/mp/webpack.base.config.js b/packages/@megalo/cli-service/lib/webpack/mp/webpack.base.config.js index 2993007..509b0f2 100644 --- a/packages/@megalo/cli-service/lib/webpack/mp/webpack.base.config.js +++ b/packages/@megalo/cli-service/lib/webpack/mp/webpack.base.config.js @@ -7,13 +7,12 @@ const VueLoaderPlugin = require('vue-loader/lib/plugin') const CopyWebpackPlugin = require('copy-webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin') -const { resolveModule, loadModule } = require('@vue/cli-shared-utils') +const { resolveModule, loadModule, error } = require('@vue/cli-shared-utils') const createMegaloTarget = require('@megalo/target') const compiler = require('@megalo/template-compiler') const { pagesEntry } = require('@megalo/entry') const { getCssExt, generateCssLoaders, checkFileExistsSync, resolve } = require('../../utils/util') const resolveClientEnv = require('../../utils/resolveClientEnv') -const appMainFile = resolve('src/index.js') module.exports = function createBaseConfig (commandName, commandOptions, projectOptions) { const cwd = process.env.MEGALO_CLI_CONTEXT || process.cwd() @@ -21,10 +20,18 @@ module.exports = function createBaseConfig (commandName, commandOptions, project const isProd = process.env.NODE_ENV === 'production' const cssExt = getCssExt(platform) const chainaConfig = new ChainableWebpackConfig() + const isUseTypescript = !!checkFileExistsSync('tsconfig.json') + const jsExt = ['js', 'ts'][+isUseTypescript] + const appMainFile = checkFileExistsSync(`src/main.${jsExt}`) || checkFileExistsSync(`src/index.${jsExt}`) + if (!appMainFile) { + error(`Failed to locate entry file in ${cwd}`) + error(`Valid entry file should be one of: main.${jsExt}, index.${jsExt}`) + process.exit(1) + } chainaConfig .mode(isProd ? 'production' : 'development') - .devtool(isProd && !projectOptions.productionSourceMap ? 'none' : 'cheap-source-map') + .devtool(isProd && !projectOptions.productionSourceMap ? 'none' : 'source-map') .target( createMegaloTarget({ compiler: Object.assign(compiler, {}), @@ -65,7 +72,7 @@ module.exports = function createBaseConfig (commandName, commandOptions, project [{ cache: true, parallel: true, - sourceMap: projectOptions.productionSourceMap ? 'cheap-source-map' : false + sourceMap: projectOptions.productionSourceMap }] ) .end() @@ -73,7 +80,13 @@ module.exports = function createBaseConfig (commandName, commandOptions, project .use( OptimizeCSSAssetsPlugin, [{ - assetNameRegExp: new RegExp(`\\.${getCssExt(platform)}$`, 'g') + assetNameRegExp: new RegExp(`\\.${getCssExt(platform)}$`, 'g'), + cssProcessorPluginOptions: { + preset: ['default', { + discardComments: { removeAll: true }, + calc: false + }] + } }] ) }) @@ -89,6 +102,7 @@ module.exports = function createBaseConfig (commandName, commandOptions, project chainaConfig.resolve.extensions .add('.vue') .add('.js') + .add('.ts') .add('.json') chainaConfig.resolve.alias @@ -109,15 +123,31 @@ module.exports = function createBaseConfig (commandName, commandOptions, project .end() .end() - generateCssLoaders(chainaConfig, projectOptions) - chainaConfig.module .rule('js') - .test(/\.js$/) + .test(/\.(ts|js)x?$/) .use('babel') .loader('babel-loader') .end() + .exclude + .add(/node_modules/) + .end() + .end() + + .rule('ts') + .test(/\.tsx?$/) + .use('ts-loader') + .loader('ts-loader') + .options({ + appendTsSuffixTo: [/\.vue$/], + transpileOnly: true + }) + .end() + .exclude + .add(/node_modules/) + .end() .end() + .rule('picture') .test(/\.(png|jpe?g|gif)$/i) .use('url') @@ -131,19 +161,10 @@ module.exports = function createBaseConfig (commandName, commandOptions, project .end() .end() + // 这里有个坑,css相关的loader必须放处理 ts 的 loader的后面,不然target那边会报错 + generateCssLoaders(chainaConfig, projectOptions) + chainaConfig - .plugin('vue-loader-plugin') - .use(VueLoaderPlugin) - .end() - .plugin('env-replace-plugin') - .use(webpack.DefinePlugin, [resolveClientEnv()]) - .end() - .plugin('mini-css-extract-plugin') - .use(MiniCssExtractPlugin, [{ filename: `static/css/[name].${cssExt}` }]) - .end() - .plugin('process-plugin') - .use(webpack.ProgressPlugin) - .end() .plugin('friendly-error-plugin') .use( FriendlyErrorsPlugin, @@ -164,6 +185,31 @@ module.exports = function createBaseConfig (commandName, commandOptions, project }] ) .end() + .plugin('process-plugin') + .use(webpack.ProgressPlugin) + .end() + .plugin('vue-loader-plugin') + .use(VueLoaderPlugin) + .end() + .plugin('env-replace-plugin') + .use(webpack.DefinePlugin, [resolveClientEnv()]) + .end() + .plugin('mini-css-extract-plugin') + .use(MiniCssExtractPlugin, [{ filename: `static/css/[name].${cssExt}` }]) + .end() + .when(isUseTypescript, config => { + const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin') + config + .plugin('fork-ts-checker-webpack-plugin') + .use( + ForkTsCheckerWebpackPlugin, + [{ + vue: true, + formatter: 'codeframe', + workers: ForkTsCheckerWebpackPlugin.TWO_CPUS_FREE + }] + ) + }) // 启用 @Megalo/API const megaloAPIPath = checkFileExistsSync(`node_modules/@megalo/api/platforms/${platform}`) @@ -198,9 +244,9 @@ module.exports = function createBaseConfig (commandName, commandOptions, project .use('eslint') .loader('eslint-loader') .options({ - // TODO 支持typescript extensions: [ '.js', + '.ts', '.jsx', '.vue' ], diff --git a/packages/@megalo/cli-service/package.json b/packages/@megalo/cli-service/package.json index b1c2739..e636966 100644 --- a/packages/@megalo/cli-service/package.json +++ b/packages/@megalo/cli-service/package.json @@ -1,7 +1,7 @@ { "name": "@megalo/cli-service", "description": ":hammer_and_wrench: megalo的开箱即用webpack小程序脚手架配置,内置megalo生态的部分插件,并提供用户自定义配置的入口(对标vue-cli 3)", - "version": "1.0.0-alpha.11", + "version": "1.0.0-alpha.15", "main": "./bin/index.js", "bin": { "megalo-cli-service": "./bin/index.js" @@ -11,8 +11,8 @@ "help": "node ./bin/index.js --help" }, "dependencies": { - "@vue/cli-shared-utils": "^3.4.1", "@megalo/entry": "^0.1.2", + "@vue/cli-shared-utils": "^3.4.1", "chalk": "^2.4.2", "commander": "^2.19.0", "copy-webpack-plugin": "^4.5.2", @@ -23,7 +23,9 @@ "eslint": "^5.12.0", "eslint-loader": "^2.1.1", "file-loader": "^2.0.0", + "fork-ts-checker-webpack-plugin": "^1.0.0", "friendly-errors-webpack-plugin": "^1.7.0", + "fs-extra": "^7.0.1", "less": "^3.8.1", "less-loader": "^4.1.0", "lodash": "^4.17.11", @@ -31,8 +33,8 @@ "mini-css-extract-plugin": "^0.4.1", "optimize-css-assets-webpack-plugin": "^5.0.1", "px2rpx-loader": "^0.1.10", - "rimraf": "^2.6.2", "terser-webpack-plugin": "^1.2.1", + "ts-loader": "^5.3.3", "url-loader": "^1.1.2", "vue-loader": "15.4.0", "vue-style-loader": "^4.1.1", diff --git a/packages/@megalo/cli/README.md b/packages/@megalo/cli/README.md index 23cc6d7..4b99bf1 100644 --- a/packages/@megalo/cli/README.md +++ b/packages/@megalo/cli/README.md @@ -6,18 +6,24 @@ install -``` -$ npm install -g @megalo/cli +``` bash +$ npm i -g sao ``` -build +build and create project +``` bash +$ sao npm:@megalo/cli your-project-name ``` -$ megalo pro-name + +enter the project root directory + +``` bash +$ cd your-project-name ``` -help +running +``` bash +$ npm run dev:wechat ``` -$ megalo -h -``` \ No newline at end of file diff --git a/packages/@megalo/cli/package.json b/packages/@megalo/cli/package.json index 44c1b82..89f2912 100644 --- a/packages/@megalo/cli/package.json +++ b/packages/@megalo/cli/package.json @@ -1,6 +1,6 @@ { "name": "@megalo/cli", - "version": "1.0.0-alpha.2", + "version": "1.0.0-alpha.3", "description": "megalo project template", "keywords": [ "vue", @@ -24,7 +24,7 @@ "files": [ "saofile.js", "cli.js", - "template", + "templates", "util" ], "scripts": { @@ -33,9 +33,8 @@ "dependencies": { "chalk": "^2.4.1", "compare-versions": "^3.4.0", - "is-email": "^1.0.0", + "execa": "^1.0.0", "latest-version": "^4.0.0", "sao": "^1.6.1" - }, - "devDependencies": {} + } } diff --git a/packages/@megalo/cli/saofile.js b/packages/@megalo/cli/saofile.js index 3f8ab34..c66a037 100644 --- a/packages/@megalo/cli/saofile.js +++ b/packages/@megalo/cli/saofile.js @@ -1,31 +1,33 @@ -const isEmail = require('is-email') const path = require('path') +const execa = require('execa') +const when = (condition, value, fallback) => (condition ? value : fallback) module.exports = { prompts () { return [ { - name: 'projectName', - message: 'project name (eg. my-megalo-project)', - default: this.outFolder - }, - { - name: 'description', - message: 'description', - default: 'a megalo project' - }, - { - name: 'author', - message: 'author', - default: this.gitUser.username || this.gitUser.name, - store: true - }, - { - name: 'email', - message: 'email', - default: this.gitUser.email, - store: true, - validate: val => (isEmail(val) ? true : 'Invalid email') + name: 'features', + message: 'Check the features needed for your project:', + type: 'checkbox', + default: ['css-pre-processors', 'eslint'], + choices: [ + { + name: 'Typescript', + value: 'typescript' + }, + { + name: 'CSS Pre-processors', + value: 'css-pre-processors' + }, + { + name: 'Eslint (check and format code)', + value: 'eslint' + }, + { + name: 'Vuex', + value: 'vuex' + } + ] }, { name: 'cssPreset', @@ -33,10 +35,19 @@ module.exports = { type: 'list', choices: [ { - name: 'sass/scss', + name: 'Sass/SCSS', value: 'scss' }, - 'less', 'stylus'] + { + name: 'Less', + value: 'less' + }, + { + name: 'Stylus', + value: 'stylus' + } + ], + when: ({ features }) => features.includes('css-pre-processors') }, { name: 'needPx2Rpx', @@ -49,23 +60,25 @@ module.exports = { message: 'Need megalo api', type: 'list', choices: ['No', 'Yes'] - }, - { - name: 'needEslint', - message: 'Need eslint to check and format code', - type: 'list', - choices: ['Yes', 'No'] } ] }, + templateData () { + return { + projectName: this.outFolder + } + }, actions () { - const { needEslint } = this.answers + const { features } = this.answers return [ { type: 'add', + templateDir: `templates/${features.includes('typescript') ? 'typescript' : 'main'}`, files: '**', filters: { - 'eslint*': needEslint === 'Yes' + 'eslint*': features.includes('eslint'), + 'src/store/**/*': features.includes('vuex'), + 'src/pages/vuex/**/*': features.includes('vuex') } }, { @@ -77,11 +90,68 @@ module.exports = { 'eslintignore': '.eslintignore', 'eslintrc': '.eslintrc.js' } + }, + { + type: 'modify', + files: 'package.json', + handler: () => { + const { features, cssPreset, needMegaloAPI } = this.answers + return { + 'name': this.outFolder, + 'version': '1.0.0', + 'private': true, + 'scripts': { + 'build:wechat': 'megalo-cli-service build', + 'build:alipay': 'megalo-cli-service build --platform alipay', + 'build:swan': 'megalo-cli-service build --platform swan', + 'dev:alipay': 'megalo-cli-service serve --platform alipay', + 'dev:swan': 'megalo-cli-service serve --platform swan', + 'dev:wechat': 'megalo-cli-service serve', + 'lint': when(features.includes('eslint'), 'eslint --fix --ext .js,.ts,.vue src') + }, + 'license': 'ISC', + 'babel': { + 'presets': [ + '@megalo/app' + ] + }, + 'devDependencies': { + '@megalo/babel-preset-app': 'latest', + '@megalo/cli-service': 'latest', + '@megalo/eslint-config-standard': when(features.includes('eslint'), 'latest'), + '@megalo/eslint-config-typescript': when(features.includes('typescript') && features.includes('eslint'), 'latest'), + '@megalo/target': 'latest', + '@megalo/template-compiler': 'latest', + '@types/node': when(features.includes('typescript'), '^11.11.4'), + 'eslint': when(features.includes('eslint'), '^5.15.3'), + 'less': when(cssPreset === 'less', '^3.8.1'), + 'less-loader': when(cssPreset === 'less', '^4.1.0'), + 'stylus': when(cssPreset === 'stylus', '^0.54.5'), + 'stylus-loader': when(cssPreset === 'stylus', '^3.0.2'), + 'node-sass': when(cssPreset === 'sass', '^4.10.0'), + 'sass-loader': when(cssPreset === 'sass', '^7.1.0'), + 'typescript': when(features.includes('typescript'), '^3.3.4000'), + 'vue-property-decorator': when(features.includes('typescript'), '^7.3.0') + }, + 'dependencies': { + '@megalo/api': when(needMegaloAPI === 'Yes', 'latest'), + '@megalo/vhtml-plugin': 'latest', + 'megalo': 'latest', + 'octoparse': '^0.3.2', + 'vuex': when(features.includes('vuex'), '^3.1.0'), + 'vuex-class': when(features.includes('vuex'), '^0.3.2') + } + } + } } ] }, async completed () { + const { features } = this.answers await this.npmInstall() + if (features.includes('eslint')) { + execa.shell('npm run lint') + } this.showProjectTips() const logCd = () => { if (this.outDir !== process.cwd()) { diff --git a/packages/@megalo/cli/template/package b/packages/@megalo/cli/template/package deleted file mode 100644 index a371c43..0000000 --- a/packages/@megalo/cli/template/package +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "<%- projectName %>", - "version": "1.0.0", - "description": "<%- description %>", - "main": "index.js", - "private": true, - "scripts": { - "build:wechat": "megalo-cli-service build", - "build:alipay": "megalo-cli-service build --platform alipay", - "build:swan": "megalo-cli-service build --platform swan", - "dev:alipay": "megalo-cli-service serve --platform alipay", - "dev:swan": "megalo-cli-service serve --platform swan", - "dev:wechat": "megalo-cli-service serve",<% if (needEslint === 'Yes') { %> - "lint": "eslint --fix --ext .js,.vue src"<% } %> - }, - "author": "<%- author %> <<%- email %>>", - "license": "ISC", - "babel": { - "presets": [ - "@megalo/app" - ] - }, - "devDependencies": { - "@megalo/babel-preset-app": "^1.0.0-alpha.1", - "@megalo/cli-service": "^1.0.0-alpha.8",<% if (needEslint === 'Yes') { %> - "@megalo/eslint-config-standard": "^1.0.0",<% } %> - "@megalo/target": "^0.5.7", - "@megalo/template-compiler": "^0.8.0",<% if (cssPreset === 'less') { %> - "less": "^3.8.1", - "less-loader": "^4.1.0"<% } else if (cssPreset === 'stylus') {%> - "stylus": "^0.54.5", - "stylus-loader": "^3.0.2"<% } else {%> - "node-sass": "^4.10.0", - "sass-loader": "^7.1.0"<% } %> - }, - "dependencies": {<% if (needMegaloAPI === 'Yes') { %> - "@megalo/api": "^0.2.2",<% } %> - "@megalo/vhtml-plugin": "^0.1.2", - "megalo": "^0.8.0", - "octoparse": "^0.3.2" - } -} diff --git a/packages/@megalo/cli/template/src/App.vue b/packages/@megalo/cli/template/src/App.vue deleted file mode 100644 index f54100c..0000000 --- a/packages/@megalo/cli/template/src/App.vue +++ /dev/null @@ -1,27 +0,0 @@ - - diff --git a/packages/@megalo/cli/templates/main/.env.development b/packages/@megalo/cli/templates/main/.env.development new file mode 100755 index 0000000..74a4546 --- /dev/null +++ b/packages/@megalo/cli/templates/main/.env.development @@ -0,0 +1 @@ +VUE_APP_TEST=我是development模式的环境变量 \ No newline at end of file diff --git a/packages/@megalo/cli/templates/main/.env.production b/packages/@megalo/cli/templates/main/.env.production new file mode 100755 index 0000000..cba7a15 --- /dev/null +++ b/packages/@megalo/cli/templates/main/.env.production @@ -0,0 +1 @@ +VUE_APP_TEST=我是production模式的环境变量 \ No newline at end of file diff --git a/packages/@megalo/cli/templates/main/README b/packages/@megalo/cli/templates/main/README new file mode 100644 index 0000000..275b7a9 --- /dev/null +++ b/packages/@megalo/cli/templates/main/README @@ -0,0 +1,21 @@ +# <%- projectName %> + +## 运行 + +微信小程序: + +```bash +npm run dev:wechat +``` + +支付宝小程序: + +```bash +npm run dev:alipay +``` + +百度智能小程序: + +```bash +npm run dev:swan +``` diff --git a/packages/@megalo/cli/templates/main/eslintignore b/packages/@megalo/cli/templates/main/eslintignore new file mode 100644 index 0000000..53ea1ed --- /dev/null +++ b/packages/@megalo/cli/templates/main/eslintignore @@ -0,0 +1,2 @@ +node_modules +dist-* diff --git a/packages/@megalo/cli/template/eslintrc b/packages/@megalo/cli/templates/main/eslintrc similarity index 58% rename from packages/@megalo/cli/template/eslintrc rename to packages/@megalo/cli/templates/main/eslintrc index 1907358..1055c43 100755 --- a/packages/@megalo/cli/template/eslintrc +++ b/packages/@megalo/cli/templates/main/eslintrc @@ -1,6 +1,9 @@ module.exports = { root: true, - extends: [ + env: { + node: true + }, + 'extends': [ '@megalo/standard' ] } diff --git a/packages/@megalo/cli/templates/main/gitignore b/packages/@megalo/cli/templates/main/gitignore new file mode 100644 index 0000000..1217c91 --- /dev/null +++ b/packages/@megalo/cli/templates/main/gitignore @@ -0,0 +1,20 @@ +node_modules +dist* + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/packages/@megalo/cli/template/megalo.config.js b/packages/@megalo/cli/templates/main/megalo.config.js similarity index 96% rename from packages/@megalo/cli/template/megalo.config.js rename to packages/@megalo/cli/templates/main/megalo.config.js index 406efeb..f57876d 100755 --- a/packages/@megalo/cli/template/megalo.config.js +++ b/packages/@megalo/cli/templates/main/megalo.config.js @@ -3,7 +3,7 @@ module.exports = { productionSourceMap: false, // 开启eslint格式化代码 - lintOnSave: <%= needEslint === 'Yes' ? true : false %>, + lintOnSave: <%= features.includes('eslint') %>, configureWebpack: config => { // 你可以在这里粗放的修改webpack的配置并返回 diff --git a/packages/@megalo/cli/templates/main/package b/packages/@megalo/cli/templates/main/package new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/packages/@megalo/cli/templates/main/package @@ -0,0 +1 @@ +{} diff --git a/packages/@megalo/cli/templates/main/src/App.vue b/packages/@megalo/cli/templates/main/src/App.vue new file mode 100644 index 0000000..e926709 --- /dev/null +++ b/packages/@megalo/cli/templates/main/src/App.vue @@ -0,0 +1,26 @@ + + diff --git a/packages/@megalo/cli/template/src/components/HelloWorld.vue b/packages/@megalo/cli/templates/main/src/components/HelloWorld.vue similarity index 100% rename from packages/@megalo/cli/template/src/components/HelloWorld.vue rename to packages/@megalo/cli/templates/main/src/components/HelloWorld.vue diff --git a/packages/@megalo/cli/templates/main/src/main.js b/packages/@megalo/cli/templates/main/src/main.js new file mode 100644 index 0000000..4a4f8e3 --- /dev/null +++ b/packages/@megalo/cli/templates/main/src/main.js @@ -0,0 +1,55 @@ +import App from './App' +import Vue from 'vue' +import VHtmlPlugin from '@megalo/vhtml-plugin'<% if (features.includes('vuex')) { %> +import Vuex from 'vuex'<% } %> + +Vue.use(VHtmlPlugin)<% if (features.includes('vuex')) { %> +Vue.use(Vuex) + +const store = require('./store').default +Vue.prototype.$store = store +<% } %> +const app = new Vue(App) + +app.$mount() + +export default { + config: { + // pages 的首个页面会被编译成首页 + pages: [ + 'pages/hello', + 'pages/my/my'<% if (features.includes('vuex')) { %>, + 'pages/vuex/vuex'<% } %> + ], + tabBar: { + color: '#333', + selectedColor: '#007d37', + list: [ + { + pagePath: 'pages/hello', + text: 'home', + iconPath: 'native/tabbar/home.png', + selectedIconPath: 'native/tabbar/home_on.png' + }, + { + pagePath: 'pages/my/my', + text: 'my', + iconPath: 'native/tabbar/mine.png', + selectedIconPath: 'native/tabbar/mine_on.png' + }<% if (features.includes('vuex')) { %>, + { + pagePath: 'pages/vuex/vuex', + text: 'vuex', + iconPath: 'native/tabbar/vue.png', + selectedIconPath: 'native/tabbar/vue_on.png' + }<% } %> + ] + }, + window: { + backgroundTextStyle: 'light', + navigationBarBackgroundColor: '#fff', + navigationBarTitleText: 'megalo project', + navigationBarTextStyle: 'black' + } + } +} diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/home.png b/packages/@megalo/cli/templates/main/src/native/tabbar/home.png new file mode 100644 index 0000000..0a21508 Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/home.png differ diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/home_on.png b/packages/@megalo/cli/templates/main/src/native/tabbar/home_on.png new file mode 100644 index 0000000..0070ec3 Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/home_on.png differ diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/mine.png b/packages/@megalo/cli/templates/main/src/native/tabbar/mine.png new file mode 100644 index 0000000..44f6cf9 Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/mine.png differ diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/mine_on.png b/packages/@megalo/cli/templates/main/src/native/tabbar/mine_on.png new file mode 100644 index 0000000..e4f2a97 Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/mine_on.png differ diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/vue.png b/packages/@megalo/cli/templates/main/src/native/tabbar/vue.png new file mode 100644 index 0000000..4d3ed2c Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/vue.png differ diff --git a/packages/@megalo/cli/templates/main/src/native/tabbar/vue_on.png b/packages/@megalo/cli/templates/main/src/native/tabbar/vue_on.png new file mode 100644 index 0000000..4f900ca Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/native/tabbar/vue_on.png differ diff --git a/packages/@megalo/cli/template/src/pages/hello.vue b/packages/@megalo/cli/templates/main/src/pages/hello.vue similarity index 81% rename from packages/@megalo/cli/template/src/pages/hello.vue rename to packages/@megalo/cli/templates/main/src/pages/hello.vue index f065f6c..2e479fd 100644 --- a/packages/@megalo/cli/template/src/pages/hello.vue +++ b/packages/@megalo/cli/templates/main/src/pages/hello.vue @@ -32,23 +32,23 @@ export default { mounted () { console.log('Page [hello] Vue mounted') }, - onLoad: function (options) { + onLoad (options) { // Do some initialize when page load. console.log('Page [hello] onLoad') }, - onReady: function () { + onReady () { // Do something when page ready. console.log('Page [hello] onReady') }, - onShow: function () { + onShow () { // Do something when page show. console.log('Page [hello] onShow') }, - onHide: function () { + onHide () { // Do something when page hide. console.log('Page [hello] onHide') }, - onUnload: function () { + onUnload () { // Do something when page close. console.log('Page [hello] onUnload') }, @@ -56,14 +56,14 @@ export default { * for other event handlers, please check https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html */ methods: { - changeStat: function () { + changeStat () { this.t++ this.color = '#' + Math.floor(Math.random() * 0xffffff).toString(16) } } } - +<% if (features.includes('css-pre-processors')) { %> +<% } else { %> +<% } %> diff --git a/packages/@megalo/cli/template/src/pages/my/my.vue b/packages/@megalo/cli/templates/main/src/pages/my/my.vue similarity index 81% rename from packages/@megalo/cli/template/src/pages/my/my.vue rename to packages/@megalo/cli/templates/main/src/pages/my/my.vue index 40b8e37..1f9574e 100644 --- a/packages/@megalo/cli/template/src/pages/my/my.vue +++ b/packages/@megalo/cli/templates/main/src/pages/my/my.vue @@ -32,23 +32,23 @@ export default { mounted () { console.log('Page [my] Vue mounted') }, - onLoad: function (options) { + onLoad (options) { // Do some initialize when page load. console.log('Page [my] onLoad') }, - onReady: function () { + onReady () { // Do something when page ready. console.log('Page [my] onReady') }, - onShow: function () { + onShow () { // Do something when page show. console.log('Page [my] onShow') }, - onHide: function () { + onHide () { // Do something when page hide. console.log('Page [my] onHide') }, - onUnload: function () { + onUnload () { // Do something when page close. console.log('Page [my] onUnload') }, @@ -56,14 +56,14 @@ export default { * for other event handlers, please check https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html */ methods: { - changeStat: function () { + changeStat () { this.t++ this.color = '#' + Math.floor(Math.random() * 0xffffff).toString(16) } } } - +<% if (features.includes('css-pre-processors')) { %> +<% } else { %> +<% } %> diff --git a/packages/@megalo/cli/templates/main/src/pages/vuex/vuex.vue b/packages/@megalo/cli/templates/main/src/pages/vuex/vuex.vue new file mode 100644 index 0000000..d18b6f9 --- /dev/null +++ b/packages/@megalo/cli/templates/main/src/pages/vuex/vuex.vue @@ -0,0 +1,47 @@ + +{ + navigationBarTitleText: 'vuex示例', + usingComponents: { + + } +} + + + + + diff --git a/packages/@megalo/cli/templates/main/src/static/imgs/megalo_logo.png b/packages/@megalo/cli/templates/main/src/static/imgs/megalo_logo.png new file mode 100644 index 0000000..48af7ea Binary files /dev/null and b/packages/@megalo/cli/templates/main/src/static/imgs/megalo_logo.png differ diff --git a/packages/@megalo/cli/templates/main/src/store/counter.js b/packages/@megalo/cli/templates/main/src/store/counter.js new file mode 100755 index 0000000..e194d6e --- /dev/null +++ b/packages/@megalo/cli/templates/main/src/store/counter.js @@ -0,0 +1,53 @@ +// root state object. +// each Vuex instance is just a single state tree. +const state = { + count: 0 +} + +// mutations are operations that actually mutates the state. +// each mutation handler gets the entire state tree as the +// first argument, followed by additional payload arguments. +// mutations must be synchronous and can be recorded by plugins +// for debugging purposes. +const mutations = { + increment (state) { + state.count++ + }, + decrement (state) { + state.count-- + } +} + +// actions are functions that cause side effects and can involve +// asynchronous operations. +const actions = { + increment: ({ commit }) => commit('increment'), + decrement: ({ commit }) => commit('decrement'), + incrementIfOdd ({ commit, state }) { + if ((state.count + 1) % 2 === 0) { + commit('increment') + } + }, + incrementAsync ({ commit }) { + return new Promise((resolve, reject) => { + setTimeout(() => { + commit('increment') + resolve() + }, 1000) + }) + } +} + +// getters are functions +const getters = { + evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' +} + +// A Vuex instance is created by combining the state, mutations, actions, +// and getters. +export default { + state, + getters, + actions, + mutations +} diff --git a/packages/@megalo/cli/templates/main/src/store/index.js b/packages/@megalo/cli/templates/main/src/store/index.js new file mode 100755 index 0000000..88ef01e --- /dev/null +++ b/packages/@megalo/cli/templates/main/src/store/index.js @@ -0,0 +1,8 @@ +import Vuex from 'vuex' +import counter from './counter' + +export default new Vuex.Store({ + modules: { + counter + } +}) diff --git a/packages/@megalo/cli/templates/typescript/.env.development b/packages/@megalo/cli/templates/typescript/.env.development new file mode 100755 index 0000000..74a4546 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/.env.development @@ -0,0 +1 @@ +VUE_APP_TEST=我是development模式的环境变量 \ No newline at end of file diff --git a/packages/@megalo/cli/templates/typescript/.env.production b/packages/@megalo/cli/templates/typescript/.env.production new file mode 100755 index 0000000..cba7a15 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/.env.production @@ -0,0 +1 @@ +VUE_APP_TEST=我是production模式的环境变量 \ No newline at end of file diff --git a/packages/@megalo/cli/templates/typescript/README b/packages/@megalo/cli/templates/typescript/README new file mode 100644 index 0000000..275b7a9 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/README @@ -0,0 +1,21 @@ +# <%- projectName %> + +## 运行 + +微信小程序: + +```bash +npm run dev:wechat +``` + +支付宝小程序: + +```bash +npm run dev:alipay +``` + +百度智能小程序: + +```bash +npm run dev:swan +``` diff --git a/packages/@megalo/cli/templates/typescript/eslintignore b/packages/@megalo/cli/templates/typescript/eslintignore new file mode 100644 index 0000000..53ea1ed --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/eslintignore @@ -0,0 +1,2 @@ +node_modules +dist-* diff --git a/packages/@megalo/cli/templates/typescript/eslintrc b/packages/@megalo/cli/templates/typescript/eslintrc new file mode 100755 index 0000000..a4f8498 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/eslintrc @@ -0,0 +1,10 @@ +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + '@megalo/standard', + '@megalo/typescript' + ] +} diff --git a/packages/@megalo/cli/templates/typescript/gitignore b/packages/@megalo/cli/templates/typescript/gitignore new file mode 100644 index 0000000..1217c91 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/gitignore @@ -0,0 +1,20 @@ +node_modules +dist* + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw* diff --git a/packages/@megalo/cli/templates/typescript/megalo.config.js b/packages/@megalo/cli/templates/typescript/megalo.config.js new file mode 100644 index 0000000..f57876d --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/megalo.config.js @@ -0,0 +1,43 @@ +module.exports = { + // 构件生产模式时是否生成source map(仅在process.env.NODE_ENV === 'production' 时该选项生效) + productionSourceMap: false, + + // 开启eslint格式化代码 + lintOnSave: <%= features.includes('eslint') %>, + + configureWebpack: config => { + // 你可以在这里粗放的修改webpack的配置并返回 + console.log('configureWebpack执行了') + return config + }, + chainWebpack: chainConfig => { + // 你可以在这里通过 https://github.com/neutrinojs/webpack-chain 来精细的修改webpack配置 + // console.log('chainWebpack执行了', chainConfig.toString()) + }, + // 原生小程序组件存放目录,默认为src/native + // 如果你有多个平台的原生组件,你应当在此目录下再新建几个子文件夹,我们约定,子文件夹名和平台的名字一致: + // 微信小程序组件则命名为 'wechat',支付宝为'alipay', 百度为 'swan' + // 如果只有一个平台,则无需再新建子文件夹 + nativeDir: '/src/native', + + css: { + loaderOptions: { + css: { + // https://github.com/webpack-contrib/css-loader#options + }, + less: { + // https://github.com/webpack-contrib/less-loader + }, + sass: { + // https://github.com/webpack-contrib/sass-loader + }, + stylus: { + // https://github.com/shama/stylus-loader + }, + // https://github.com/megalojs/megalo-px2rpx-loader + px2rpx: <% if (needPx2Rpx === 'Yes') { %>{ + rpxUnit: 0.5 + }<% } else {%>false<% } %> + } + } +} diff --git a/packages/@megalo/cli/templates/typescript/package b/packages/@megalo/cli/templates/typescript/package new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/package @@ -0,0 +1 @@ +{} diff --git a/packages/@megalo/cli/templates/typescript/src/App.vue b/packages/@megalo/cli/templates/typescript/src/App.vue new file mode 100644 index 0000000..ccf80c7 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/App.vue @@ -0,0 +1,52 @@ + diff --git a/packages/@megalo/cli/templates/typescript/src/components/HelloWorld.vue b/packages/@megalo/cli/templates/typescript/src/components/HelloWorld.vue new file mode 100644 index 0000000..f674b8c --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/components/HelloWorld.vue @@ -0,0 +1,23 @@ + + + + + + diff --git a/packages/@megalo/cli/templates/typescript/src/main.ts b/packages/@megalo/cli/templates/typescript/src/main.ts new file mode 100644 index 0000000..3dee220 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/main.ts @@ -0,0 +1,70 @@ +import App from './App.vue' +import Vue from 'vue' +import { Component } from 'vue-property-decorator' +import VHtmlPlugin from '@megalo/vhtml-plugin'<% if (features.includes('vuex')) { %> +import Vuex from 'vuex'<% } %> + +Vue.use(VHtmlPlugin)<% if (features.includes('vuex')) { %> +Vue.use(Vuex) + +const store = require('./store').default +Vue.prototype.$store = store +<% } %> +// https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/page.html +Component.registerHooks([ + 'onLoad', // 监听页面加载 + 'onShow', // 监听页面显示 + 'onReady', // 监听页面初次渲染完成 + 'onHide', // 监听页面隐藏 + 'onUnload', // 监听页面卸载 + 'onPullDownRefresh', // 监听用户下拉动作 + 'onReachBottom', // 页面上拉触底事件的处理函数 + 'onShareAppMessage', // 用户点击右上角分享 + 'onPageScroll', // 页面滚动 + 'onTabItemTap' // 当前是 tab 页时, 点击 tab 时触发 +]) + +const app = new Vue(App) + +app.$mount() + +export default { + config: { + // pages 的首个页面会被编译成首页 + pages: [ + 'pages/hello', + 'pages/my/my'<% if (features.includes('vuex')) { %>, + 'pages/vuex/vuex'<% } %> + ], + tabBar: { + color: '#333', + selectedColor: '#007d37', + list: [ + { + pagePath: 'pages/hello', + text: 'home', + iconPath: 'native/tabbar/home.png', + selectedIconPath: 'native/tabbar/home_on.png' + }, + { + pagePath: 'pages/my/my', + text: 'my', + iconPath: 'native/tabbar/mine.png', + selectedIconPath: 'native/tabbar/mine_on.png' + }<% if (features.includes('vuex')) { %>, + { + pagePath: 'pages/vuex/vuex', + text: 'vuex', + iconPath: 'native/tabbar/vue.png', + selectedIconPath: 'native/tabbar/vue_on.png' + }<% } %> + ] + }, + window: { + backgroundTextStyle: 'light', + navigationBarBackgroundColor: '#fff', + navigationBarTitleText: 'megalo typescript project', + navigationBarTextStyle: 'black' + } + } +} diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/home.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/home.png new file mode 100644 index 0000000..0a21508 Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/home.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/home_on.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/home_on.png new file mode 100644 index 0000000..0070ec3 Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/home_on.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine.png new file mode 100644 index 0000000..44f6cf9 Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine_on.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine_on.png new file mode 100644 index 0000000..e4f2a97 Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/mine_on.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue.png new file mode 100644 index 0000000..4d3ed2c Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue_on.png b/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue_on.png new file mode 100644 index 0000000..4f900ca Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/native/tabbar/vue_on.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/pages/hello.vue b/packages/@megalo/cli/templates/typescript/src/pages/hello.vue new file mode 100644 index 0000000..d007d53 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/pages/hello.vue @@ -0,0 +1,119 @@ + + + +<% if (features.includes('css-pre-processors')) { %> +<% } else { %> +<% } %> diff --git a/packages/@megalo/cli/templates/typescript/src/pages/my/my.vue b/packages/@megalo/cli/templates/typescript/src/pages/my/my.vue new file mode 100644 index 0000000..80f6465 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/pages/my/my.vue @@ -0,0 +1,105 @@ + + + +<% if (features.includes('css-pre-processors')) { %> +<% } else { %> +<% } %> diff --git a/packages/@megalo/cli/templates/typescript/src/pages/vuex/vuex.vue b/packages/@megalo/cli/templates/typescript/src/pages/vuex/vuex.vue new file mode 100644 index 0000000..4d02318 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/pages/vuex/vuex.vue @@ -0,0 +1,44 @@ + +{ + navigationBarTitleText: 'vuex示例', + usingComponents: { + + } +} + + + + + diff --git a/packages/@megalo/cli/templates/typescript/src/shims-vue.d.ts b/packages/@megalo/cli/templates/typescript/src/shims-vue.d.ts new file mode 100644 index 0000000..d552178 --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/shims-vue.d.ts @@ -0,0 +1,6 @@ +declare module '*.vue' { + import Vue from 'vue'; + export default Vue; +} + +declare function getApp() diff --git a/packages/@megalo/cli/templates/typescript/src/static/imgs/megalo_logo.png b/packages/@megalo/cli/templates/typescript/src/static/imgs/megalo_logo.png new file mode 100644 index 0000000..48af7ea Binary files /dev/null and b/packages/@megalo/cli/templates/typescript/src/static/imgs/megalo_logo.png differ diff --git a/packages/@megalo/cli/templates/typescript/src/store/counter.ts b/packages/@megalo/cli/templates/typescript/src/store/counter.ts new file mode 100644 index 0000000..e194d6e --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/store/counter.ts @@ -0,0 +1,53 @@ +// root state object. +// each Vuex instance is just a single state tree. +const state = { + count: 0 +} + +// mutations are operations that actually mutates the state. +// each mutation handler gets the entire state tree as the +// first argument, followed by additional payload arguments. +// mutations must be synchronous and can be recorded by plugins +// for debugging purposes. +const mutations = { + increment (state) { + state.count++ + }, + decrement (state) { + state.count-- + } +} + +// actions are functions that cause side effects and can involve +// asynchronous operations. +const actions = { + increment: ({ commit }) => commit('increment'), + decrement: ({ commit }) => commit('decrement'), + incrementIfOdd ({ commit, state }) { + if ((state.count + 1) % 2 === 0) { + commit('increment') + } + }, + incrementAsync ({ commit }) { + return new Promise((resolve, reject) => { + setTimeout(() => { + commit('increment') + resolve() + }, 1000) + }) + } +} + +// getters are functions +const getters = { + evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd' +} + +// A Vuex instance is created by combining the state, mutations, actions, +// and getters. +export default { + state, + getters, + actions, + mutations +} diff --git a/packages/@megalo/cli/templates/typescript/src/store/index.ts b/packages/@megalo/cli/templates/typescript/src/store/index.ts new file mode 100644 index 0000000..88ef01e --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/src/store/index.ts @@ -0,0 +1,8 @@ +import Vuex from 'vuex' +import counter from './counter' + +export default new Vuex.Store({ + modules: { + counter + } +}) diff --git a/packages/@megalo/cli/templates/typescript/tsconfig.json b/packages/@megalo/cli/templates/typescript/tsconfig.json new file mode 100644 index 0000000..b1052bd --- /dev/null +++ b/packages/@megalo/cli/templates/typescript/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + // 与 Vue 的浏览器支持保持一致 + "target": "es5", + // 这可以对 `this` 上的数据属性进行更严格的推断 + "strict": true, + "sourceMap": true, + "isolatedModules": true, + // 如果使用 webpack 2+ 或 rollup,可以利用 tree-shake: + "module": "esnext", + "moduleResolution": "node", + "baseUrl": "./", + // "outDir": "./dist/", + "paths": { + "vue": [ + "node_modules/megalo" + ], + "@/*": [ + "src/*" + ] + }, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "noImplicitAny": false, + "skipLibCheck": true, + "strictPropertyInitialization": false, + "experimentalDecorators": true, + "esModuleInterop": true + }, + "include": [ + "./src/**/*" + ], + "exclude": [ + "node_modules" + ], + "typeAcquisition": { + "enable": true + } +}