Commit a34f5f1104d224709132b9b408523ce3dccf3bb4
1 parent
39d9f8fd
tiny preview: build preview engine with webpack outputDir
Showing
8 changed files
with
209 additions
and
13 deletions
back-end/h5-api/.gitignore
back-end/h5-api/api/work/controllers/Work.js
| @@ -9,6 +9,7 @@ module.exports = { | @@ -9,6 +9,7 @@ module.exports = { | ||
| 9 | // GET /previewOne | 9 | // GET /previewOne |
| 10 | // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs | 10 | // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs |
| 11 | previewOne: async (ctx) => { | 11 | previewOne: async (ctx) => { |
| 12 | - return ctx.render('engine', {work: { page2: []}}); | 12 | + const work = await strapi.services.work.findOne(ctx.params); |
| 13 | + return ctx.render('engine', { work }); | ||
| 13 | } | 14 | } |
| 14 | }; | 15 | }; |
back-end/h5-api/config/hook.json
back-end/h5-api/public/engine-asset/.gitkeep
0 → 100644
back-end/h5-api/views/engine.ejs
0 → 100644
| 1 | +<html> | ||
| 2 | + | ||
| 3 | +<head> | ||
| 4 | + <meta charset="UTF-8"> | ||
| 5 | + <title>work.html</title> | ||
| 6 | + <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> | ||
| 7 | + <meta content="yes" name="apple-mobile-web-app-capable"> | ||
| 8 | + <meta content="black" name="apple-mobile-web-app-status-bar-style"> | ||
| 9 | + <meta content="telephone=no" name="format-detection"> | ||
| 10 | + <meta content="email=no" name="format-detection"> | ||
| 11 | + <script src="https://cdn.jsdelivr.net/npm/vue"></script> | ||
| 12 | + <script type="text/javascript" src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/flexible.js"></script> | ||
| 13 | + <!-- <link rel="stylesheet" href="/be-static/be-static-luban-h5/engine/engine.css"> --> | ||
| 14 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.min.css"> | ||
| 15 | + <link rel="stylesheet" href="https://meyerweb.com/eric/tools/css/reset/reset.css"> | ||
| 16 | + <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.min.js"></script> | ||
| 17 | + <script>window.__work = <%- JSON.stringify(work) %></script> | ||
| 18 | + <script src="/engine-assets/engine.js"></script> | ||
| 19 | + <style> | ||
| 20 | + .swiper-container { | ||
| 21 | + width: 100%; | ||
| 22 | + height: 100vh; | ||
| 23 | + } | ||
| 24 | + </style> | ||
| 25 | +</head> | ||
| 26 | + | ||
| 27 | +<body> | ||
| 28 | + <div id="app"> | ||
| 29 | + <engine /> | ||
| 30 | + </div> | ||
| 31 | + <script> | ||
| 32 | + // Vue.component('engine', window.Engine) | ||
| 33 | + new Vue({ | ||
| 34 | + el: '#app', | ||
| 35 | + data: { | ||
| 36 | + message: 'Hello Vue!' | ||
| 37 | + }, | ||
| 38 | + // render: function (h) { | ||
| 39 | + // return (<engine />) | ||
| 40 | + // } | ||
| 41 | + }); | ||
| 42 | + </script> | ||
| 43 | + <script> | ||
| 44 | + var mySwiper = new Swiper('.swiper-container', { | ||
| 45 | + // Optional parameters | ||
| 46 | + direction: 'vertical', | ||
| 47 | + loop: false, | ||
| 48 | + // If we need pagination | ||
| 49 | + pagination: { | ||
| 50 | + el: '.swiper-pagination', | ||
| 51 | + }, | ||
| 52 | + // Navigation arrows | ||
| 53 | + navigation: { | ||
| 54 | + nextEl: '.swiper-button-next', | ||
| 55 | + prevEl: '.swiper-button-prev', | ||
| 56 | + }, | ||
| 57 | + // And if we need scrollbar | ||
| 58 | + scrollbar: { | ||
| 59 | + el: '.swiper-scrollbar', | ||
| 60 | + }, | ||
| 61 | + }); | ||
| 62 | + </script> | ||
| 63 | + <!-- build:js scripts/vendor.js --> | ||
| 64 | + <!-- endbuild --> | ||
| 65 | +</body> | ||
| 66 | + | ||
| 67 | +</html> | ||
| 0 | \ No newline at end of file | 68 | \ No newline at end of file |
front-end/h5/build/engine.webpack.js
0 → 100644
| 1 | +let path = require('path') | ||
| 2 | +let env = { NODE_ENV: '"production"' } | ||
| 3 | +let ora = require('ora') | ||
| 4 | +let rm = require('rimraf') | ||
| 5 | +let chalk = require('chalk') | ||
| 6 | +let webpack = require('webpack') | ||
| 7 | + | ||
| 8 | +function assetsPath (_path) { | ||
| 9 | + let assetsSubDirectory = '/engine-assets' | ||
| 10 | + return path.posix.join(assetsSubDirectory, _path) | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +function resolve (dir) { | ||
| 14 | + // console.log(path.join(__dirname, '..', '../../back-end/preview/public/be-static-luban-h5/engine')); | ||
| 15 | + return path.join(__dirname, '..', dir) | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +const engineBuildOutputDir = resolve('../../back-end/h5-api/public/engine-assets') | ||
| 19 | + | ||
| 20 | +process.env.NODE_ENV = 'production' | ||
| 21 | + | ||
| 22 | +let spinner = ora('building for production...') | ||
| 23 | +spinner.start() | ||
| 24 | + | ||
| 25 | +let webpackConfig = { | ||
| 26 | + mode: 'production', | ||
| 27 | + entry: { | ||
| 28 | + engine: './src/engine-entry.js' | ||
| 29 | + }, | ||
| 30 | + // devtool: config.build.productionSourceMap ? '#source-map' : false, | ||
| 31 | + devtool: '#source-map', | ||
| 32 | + output: { | ||
| 33 | + path: engineBuildOutputDir, | ||
| 34 | + filename: '[name].js', | ||
| 35 | + // publicPath: '/public-path', | ||
| 36 | + library: 'Engine' | ||
| 37 | + }, | ||
| 38 | + resolve: { | ||
| 39 | + extensions: ['.js', '.vue', '.json'] | ||
| 40 | + }, | ||
| 41 | + externals: { | ||
| 42 | + }, | ||
| 43 | + module: { | ||
| 44 | + rules: [ | ||
| 45 | + { | ||
| 46 | + test: /\.vue$/, | ||
| 47 | + loader: 'vue-loader' | ||
| 48 | + }, | ||
| 49 | + { | ||
| 50 | + test: /\.css$/, | ||
| 51 | + use: [ | ||
| 52 | + 'vue-style-loader', | ||
| 53 | + { | ||
| 54 | + loader: 'css-loader', | ||
| 55 | + options: { | ||
| 56 | + // enable CSS Modules | ||
| 57 | + modules: true, | ||
| 58 | + // customize generated class names | ||
| 59 | + localIdentName: '[local]_[hash:base64:8]' | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | + ] | ||
| 63 | + }, | ||
| 64 | + { | ||
| 65 | + test: /\.js$/, | ||
| 66 | + loader: 'babel-loader', | ||
| 67 | + include: [resolve('src'), resolve('test')] | ||
| 68 | + }, | ||
| 69 | + { | ||
| 70 | + test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, | ||
| 71 | + loader: 'url-loader', | ||
| 72 | + options: { | ||
| 73 | + limit: 10000, | ||
| 74 | + name: assetsPath('img/[name].[hash:7].[ext]') | ||
| 75 | + } | ||
| 76 | + }, | ||
| 77 | + { | ||
| 78 | + test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, | ||
| 79 | + loader: 'url-loader', | ||
| 80 | + options: { | ||
| 81 | + limit: 10000, | ||
| 82 | + name: assetsPath('fonts/[name].[hash:7].[ext]') | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + ] | ||
| 86 | + }, | ||
| 87 | + plugins: [ | ||
| 88 | + new webpack.DefinePlugin({ | ||
| 89 | + 'process.env': env | ||
| 90 | + }) | ||
| 91 | + ] | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +rm(engineBuildOutputDir, err => { | ||
| 95 | + if (err) throw err | ||
| 96 | + webpack(webpackConfig, function (err, stats) { | ||
| 97 | + spinner.stop() | ||
| 98 | + if (err) throw err | ||
| 99 | + // process.stdout.write( | ||
| 100 | + // stats.toString({ | ||
| 101 | + // colors: true, | ||
| 102 | + // modules: true, | ||
| 103 | + // children: true, | ||
| 104 | + // chunks: true, | ||
| 105 | + // chunkModules: true | ||
| 106 | + // }) + '\n\n' | ||
| 107 | + // ) | ||
| 108 | + | ||
| 109 | + console.log(chalk.cyan(' Build complete.\n')) | ||
| 110 | + console.log( | ||
| 111 | + chalk.yellow( | ||
| 112 | + ' Tip: built files are meant to be served over an HTTP server.\n' + | ||
| 113 | + " Opening index.html over file:// won't work.\n" | ||
| 114 | + ) | ||
| 115 | + ) | ||
| 116 | + }) | ||
| 117 | +}) |
front-end/h5/src/components/core/editor/engine/index.js renamed to front-end/h5/src/engine-entry.js
| @@ -5,14 +5,13 @@ import Vue from 'vue' | @@ -5,14 +5,13 @@ import Vue from 'vue' | ||
| 5 | import Antd from 'ant-design-vue' | 5 | import Antd from 'ant-design-vue' |
| 6 | import 'ant-design-vue/dist/antd.css' | 6 | import 'ant-design-vue/dist/antd.css' |
| 7 | import 'font-awesome/css/font-awesome.min.css' | 7 | import 'font-awesome/css/font-awesome.min.css' |
| 8 | -import loadPluginMixin from '../../../../mixins/load-plugins.js' | ||
| 9 | -import Element from '../../models/element' | ||
| 10 | - | 8 | +import { pluginsList } from './mixins/load-plugins.js' |
| 9 | +import Element from './components/core/models/element' | ||
| 11 | Vue.config.productionTip = false | 10 | Vue.config.productionTip = false |
| 12 | Vue.use(Antd) | 11 | Vue.use(Antd) |
| 12 | + | ||
| 13 | const Engine = { | 13 | const Engine = { |
| 14 | name: 'engine', | 14 | name: 'engine', |
| 15 | - mixins: [loadPluginMixin], | ||
| 16 | methods: { | 15 | methods: { |
| 17 | renderPreview (h, _elements) { | 16 | renderPreview (h, _elements) { |
| 18 | const elements = _elements.map(element => new Element(element)) | 17 | const elements = _elements.map(element => new Element(element)) |
| @@ -54,9 +53,19 @@ const Engine = { | @@ -54,9 +53,19 @@ const Engine = { | ||
| 54 | } | 53 | } |
| 55 | } | 54 | } |
| 56 | 55 | ||
| 57 | -new Vue({ | ||
| 58 | - components: { | ||
| 59 | - engine: Engine | ||
| 60 | - }, | ||
| 61 | - render: h => h('engine') | ||
| 62 | -}).$mount('#app') | 56 | +const install = function (Vue) { |
| 57 | + Vue.component(Engine.name, Engine) | ||
| 58 | + pluginsList.forEach(plugin => { | ||
| 59 | + Vue.component(plugin.name, plugin.component) | ||
| 60 | + }) | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +// auto install | ||
| 64 | +if (typeof window !== 'undefined' && window.Vue) { | ||
| 65 | + install(window.Vue) | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | +export default { | ||
| 69 | + install, | ||
| 70 | + Engine | ||
| 71 | +} |
front-end/h5/src/mixins/load-plugins.js
| @@ -4,7 +4,7 @@ import LbpPicture from '../components/plugins/lbp-picture' | @@ -4,7 +4,7 @@ import LbpPicture from '../components/plugins/lbp-picture' | ||
| 4 | import LbpText from '../components/plugins/lbp-text' | 4 | import LbpText from '../components/plugins/lbp-text' |
| 5 | import LbpFormInput from '../components/plugins/lbp-form-input' | 5 | import LbpFormInput from '../components/plugins/lbp-form-input' |
| 6 | 6 | ||
| 7 | -const pluginsList = [ | 7 | +export const pluginsList = [ |
| 8 | { | 8 | { |
| 9 | title: '图片', | 9 | title: '图片', |
| 10 | icon: 'photo', | 10 | icon: 'photo', |