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 | 9 | // GET /previewOne |
| 10 | 10 | // strapi-hook-ejs: https://github.com/strapi/strapi/tree/master/packages/strapi-hook-ejs |
| 11 | 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 | 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 | 5 | import Antd from 'ant-design-vue' |
| 6 | 6 | import 'ant-design-vue/dist/antd.css' |
| 7 | 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 | 10 | Vue.config.productionTip = false |
| 12 | 11 | Vue.use(Antd) |
| 12 | + | |
| 13 | 13 | const Engine = { |
| 14 | 14 | name: 'engine', |
| 15 | - mixins: [loadPluginMixin], | |
| 16 | 15 | methods: { |
| 17 | 16 | renderPreview (h, _elements) { |
| 18 | 17 | const elements = _elements.map(element => new Element(element)) |
| ... | ... | @@ -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 | 4 | import LbpText from '../components/plugins/lbp-text' |
| 5 | 5 | import LbpFormInput from '../components/plugins/lbp-form-input' |
| 6 | 6 | |
| 7 | -const pluginsList = [ | |
| 7 | +export const pluginsList = [ | |
| 8 | 8 | { |
| 9 | 9 | title: '图片', |
| 10 | 10 | icon: 'photo', | ... | ... |