UNPKG

weex-ui-demo

Version:

A rich interaction, lightweight, high performance UI library based on Weex

303 lines (279 loc) 9.02 kB
const path = require('path'); const fs = require('fs-extra'); const uppercamelize = require('uppercamelcase'); const webpack = require('webpack'); const config = require('./config'); const helper = require('./helper'); const glob = require('glob'); const vueLoaderConfig = require('./vue-loader.conf'); const vueWebTemp = helper.rootNode(config.templateDir); const hasPluginInstalled = fs.existsSync(helper.rootNode(config.pluginFilePath)); const isWin = /^win/.test(process.platform); const webEntry = {}; const weexEntry = {}; // Wraping the entry file for web. const getWebEntryFileContent = (entryPath, vueFilePath) => { let relativeVuePath = path.relative(path.join(entryPath, '../'), vueFilePath); let relativeEntryPath = helper.root(config.entryFilePath); let relativePluginPath = helper.rootNode(config.pluginFilePath); let contents = ''; let entryContents = fs.readFileSync(relativeEntryPath).toString(); if (isWin) { relativeVuePath = relativeVuePath.replace(/\\/g, '\\\\'); relativePluginPath = relativePluginPath.replace(/\\/g, '\\\\'); } if (hasPluginInstalled) { contents += `\n// If detact plugins/plugin.js is exist, import and the plugin.js\n`; contents += `import plugins from '${relativePluginPath}';\n`; contents += `plugins.forEach(function (plugin) {\n\tweex.install(plugin)\n});\n\n`; entryContents = entryContents.replace(/weex\.init/, match => `${contents}${match}`); contents = '' } // NOTE: web端不打包下面的代码 // contents += ` // const App = require('${relativeVuePath}'); // new Vue(Vue.util.extend({el: '#root'}, App)); // `; return entryContents + contents; } // Wraping the entry file for native. const getNativeEntryFileContent = (entryPath, vueFilePath) => { let relativeVuePath = path.relative(path.join(entryPath, '../'), vueFilePath); let contents = ''; if (isWin) { relativeVuePath = relativeVuePath.replace(/\\/g, '\\\\'); } contents += `import App from '${relativeVuePath}' App.el = '#root' new Vue(App) `; return contents; } // Retrieve entry file mappings by function recursion const getEntryFile = (dir) => { dir = dir || config.sourceDir; const entries = glob.sync(`${dir}/${config.entryFilter}`, config.entryFilterOptions); entries.forEach(entry => { const extname = path.extname(entry); const basename = entry.replace(`${dir}/`, '').replace(extname, ''); const templatePathForWeb = path.join(vueWebTemp, basename + '.web.js'); const templatePathForNative = path.join(vueWebTemp, basename + '.js'); fs.outputFileSync(templatePathForWeb, getWebEntryFileContent(templatePathForWeb, entry)); fs.outputFileSync(templatePathForNative, getNativeEntryFileContent(templatePathForNative, entry)); webEntry[basename] = templatePathForWeb; weexEntry[basename] = templatePathForNative; }) } // Generate an entry file array before writing a webpack configuration getEntryFile(); // getRoutes const getRoutes = () => { let routesConfig = fs.readFileSync(helper.root('/routes/config.json')).toString(); routesConfig = JSON.parse(routesConfig) let routes = [] let entry = {} for (let key in routesConfig) { if (entry[routesConfig[key].type]) { entry[routesConfig[key].type].push(`'${key}'`) } else { entry[routesConfig[key].type] = [] } routes.push(`{ path: '${routesConfig[key].path}', component: require('@/${routesConfig[key].jsPath}') }`) } const content = `// index.js由webpack打包生成,无需更改 export default ${JSON.stringify(routes, null, 2).replace(/"/g, '')}\n` const examples = `// examples.js由webpack打包生成,无需更改 export default ${JSON.stringify(entry, null, 2).replace(/"/g, '')}\n` fs.outputFileSync(helper.root('/routes/example.conf.js'), examples) fs.outputFileSync(helper.root('/routes/index.js'), content) } getRoutes() // getIndexEntry const getIndexEntry = () => { const components = fs.readdirSync(helper.rootNode('packages')).filter(name => name !== 'style') const importList = components.map(name => `import ${uppercamelize(name)} from './packages/${name}'`) const exportList = components.map(name => `${uppercamelize(name)}`) const content = `// examples.js由webpack打包生成,无需更改 ${importList.join('\n')} export { ${exportList.join(',\n ')} }\n` fs.writeFileSync(path.join(__dirname, '../index.js'), content) } getIndexEntry() const createLintingRule = () => ({ test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', include: [helper.rootNode('src'), helper.rootNode('test')], options: { formatter: require('eslint-friendly-formatter'), emitWarning: !config.dev.showEslintErrorsInOverlay } }) const useEslint = config.dev.useEslint ? [createLintingRule()] : [] /** * Plugins for webpack configuration. */ const plugins = [ /** * Plugin: webpack.DefinePlugin * Description: The DefinePlugin allows you to create global constants which can be configured at compile time. * * See: https://webpack.js.org/plugins/define-plugin/ */ new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': config.dev.env } }), /* * Plugin: BannerPlugin * Description: Adds a banner to the top of each generated chunk. * See: https://webpack.js.org/plugins/banner-plugin/ */ new webpack.BannerPlugin({ banner: '// { "framework": "Vue"} \n', raw: true, exclude: 'Vue' }) ]; // Config for compile jsbundle for web. const webConfig = { entry: Object.assign(webEntry, { 'vendor': [path.resolve('node_modules/phantom-limb/index.js')] }), output: { path: helper.rootNode('../dist'), filename: '[name].web.js' }, /** * Options affecting the resolving of modules. * See http://webpack.github.io/docs/configuration.html#resolve */ resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': helper.resolve('src'), packages: path.resolve(__dirname, '../packages') } }, /* * Options affecting the resolving of modules. * * See: http://webpack.github.io/docs/configuration.html#module */ module: { // webpack 2.0 rules: useEslint.concat([ { test: /\.js$/, use: [{ loader: 'babel-loader' }], exclude: config.excludeModuleReg }, { test: /\.vue(\?[^?]+)?$/, use: [{ loader: 'vue-loader', options: Object.assign(vueLoaderConfig({useVue: true, usePostCSS: false}), { /** * important! should use postTransformNode to add $processStyle for * inline style prefixing. */ optimizeSSR: false, postcss: [ // to convert weex exclusive styles. require('postcss-plugin-weex')(), require('autoprefixer')({ browsers: ['> 0.1%', 'ios >= 8', 'not ie < 12'] }), require('postcss-plugin-px2rem')({ // base on 750px standard. rootValue: 75, // to leave 1px alone. minPixelValue: 1.01 }) ], compilerModules: [ { postTransformNode: el => { // to convert vnode for weex components. require('weex-vue-precompiler')()(el) } } ] }) }], exclude: config.excludeModuleReg } ]) }, /* * Add additional plugins to the compiler. * * See: http://webpack.github.io/docs/configuration.html#plugins */ plugins: plugins }; // Config for compile jsbundle for native. const weexConfig = { entry: weexEntry, output: { path: path.join(__dirname, '../dist'), filename: '[name].js' }, /** * Options affecting the resolving of modules. * See http://webpack.github.io/docs/configuration.html#resolve */ resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': helper.resolve('src'), packages: path.resolve(__dirname, '../packages') } }, /* * Options affecting the resolving of modules. * * See: http://webpack.github.io/docs/configuration.html#module */ module: { rules: [ { test: /\.js$/, use: [{ loader: 'babel-loader' }], exclude: config.excludeModuleReg }, { test: /\.vue(\?[^?]+)?$/, use: [{ loader: 'weex-loader', options: vueLoaderConfig({useVue: false}) }], exclude: config.excludeModuleReg } ] }, /* * Add additional plugins to the compiler. * * See: http://webpack.github.io/docs/configuration.html#plugins */ plugins: plugins, /* * Include polyfills or mocks for various node stuff * Description: Node configuration * * See: https://webpack.github.io/docs/configuration.html#node */ node: config.nodeConfiguration }; module.exports = [webConfig, weexConfig];