| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| const path = require('path') |
| const glob = require('globby') |
| const webpack = require('webpack') |
| const VueLoaderPlugin = require('vue-loader/lib/plugin') |
| const HtmlWebpackPlugin = require('html-webpack-plugin') |
| const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
| const isProduction = process.env.NODE_ENV !== 'development' |
| |
| const resolve = dir => path.join(__dirname, '..', dir) |
| |
| const assetsDir = resolve('src') |
| const distDir = resolve('dist') |
| const viewDir = resolve('src/view') |
| |
| |
| function moduleName (modules) { |
| let filename = path.basename(modules) |
| let parts = filename.split('.') |
| parts.pop() |
| filename = parts.join('.') |
| return path.dirname(modules) + '/' + filename |
| } |
| |
| const jsEntry = (() => { |
| const obj = {} |
| const files = glob.sync(['js/conf/*/!(_*).js'], { cwd: assetsDir }) |
| files.forEach(val => { |
| let parts = val.split(/[\\/]/) |
| parts.shift() |
| parts.shift() |
| let modules = parts.join('/') |
| let entry = moduleName(modules) |
| obj[entry] = ['babel-polyfill', val] |
| }) |
| return obj |
| })() |
| |
| const minifierConfig = isProduction ? { |
| removeComments: true, |
| removeCommentsFromCDATA: true, |
| collapseWhitespace: true, |
| collapseBooleanAttributes: true, |
| removeRedundantAttributes: true, |
| useShortDoctype: true, |
| minifyJS: true, |
| removeScriptTypeAttributes: true, |
| maxLineLength: 1024 |
| } : false |
| |
| const getPageEntry = view => jsEntry[view] ? view : '' |
| |
| // Redirect output page |
| const pageRewriter = { |
| 'view/home/index.*': 'index.html' |
| } |
| |
| const isEmpty = o => { |
| for (let k in o) { |
| if (o.hasOwnProperty(k)) { |
| return |
| } |
| } |
| return true |
| } |
| |
| const unixPath = v => v.replace(/\\/g, '/') |
| |
| const rewriterPath = p => { |
| if (isEmpty(pageRewriter)) { |
| return |
| } |
| |
| for (let k in pageRewriter) { |
| let regx = new RegExp(k) |
| |
| if (regx.test(unixPath(p))) { |
| return pageRewriter[k] |
| } |
| } |
| } |
| const version = new Date().getTime(); |
| const pages = glob.sync(['*/!(_*).html'], { cwd: viewDir }).map(p => { |
| let pagePath = `${path.join(viewDir, p)}` |
| let newPagePath = rewriterPath(pagePath) |
| |
| let entry = getPageEntry(p.replace('.html', '')) |
| let chunks = ['common'] |
| if (entry) { |
| chunks.push(entry) |
| } |
| return new HtmlWebpackPlugin({ |
| filename: newPagePath || path.join('view', p), |
| template: `${path.join('src/view', p)}`, |
| cache: true, |
| favicon:'./favicon.png', |
| inject: true, |
| hash: version, |
| chunks: chunks, |
| minify: minifierConfig |
| }) |
| }) |
| const baseConfig = { |
| entry: jsEntry, |
| output: { |
| path: distDir, |
| publicPath: '/', |
| filename: 'js/[name].[chunkhash:7]'+version+'.js' |
| }, |
| module: { |
| rules: [ |
| { |
| test: /\.(js|vue)$/, |
| loader: 'eslint-loader', |
| enforce: 'pre', |
| include: [resolve('src')], |
| options: { |
| formatter: require('eslint-friendly-formatter'), |
| emitWarning: true |
| } |
| }, |
| { |
| test: /\.vue$/, |
| loader: 'vue-loader', |
| options: { |
| hotReload: !isProduction |
| } |
| }, |
| { |
| test: /\.js$/, |
| exclude: /(node_modules|bower_components)/, |
| use: [ |
| { |
| loader: 'babel-loader', |
| options: { |
| cacheDirectory: true, |
| cacheIdentifier: true |
| } |
| } |
| ] |
| }, |
| { |
| test: /\.(sa|sc|c)ss$/, |
| use: [ |
| { |
| loader: MiniCssExtractPlugin.loader, |
| options: { |
| hmr: !isProduction, |
| }, |
| }, |
| 'css-loader', |
| { |
| loader: 'postcss-loader', |
| options: { |
| plugins: (loader) => [ |
| require('autoprefixer')({ |
| overrideBrowserslist: [ |
| "Android 4.1", |
| "iOS 7.1", |
| "Chrome > 31", |
| "ff > 31", |
| "ie >= 8" |
| ] |
| }), |
| require('cssnano') |
| ] |
| } |
| }, |
| 'sass-loader' |
| ] |
| }, |
| { |
| test: /\.(png|jpe?g|gif|svg|cur)(\?.*)?$/, |
| loader: 'file-loader', |
| options: { |
| esModule: false, |
| name: 'images/[name].[ext]?[hash]' |
| } |
| }, |
| { |
| test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, |
| loader: 'url-loader', |
| options: { |
| esModule: false, |
| limit: 10000, |
| // publicPath: distDir, |
| name: 'font/[name].[hash:7].[ext]' |
| } |
| } |
| ] |
| }, |
| resolve: { |
| modules: [ |
| resolve('node_modules'), |
| resolve('src'), |
| resolve('src/js') |
| ], |
| alias: { |
| '@': resolve('src/js'), |
| '~': resolve('src/lib'), |
| 'jquery':'jquery/dist/jquery.min.js', |
| 'jquery-ui': 'jquery-ui' |
| }, |
| extensions: ['*', '.js', 'json', '.vue', '.scss'] |
| }, |
| plugins: [ |
| new VueLoaderPlugin(), |
| new webpack.ProvidePlugin({ vue: 'Vue', _: 'lodash',jQuery:"jquery/dist/jquery.min.js",$:"jquery/dist/jquery.min.js" }), |
| new webpack.DefinePlugin({ |
| PUBLIC_PATH: JSON.stringify(process.env.PUBLIC_PATH ? process.env.PUBLIC_PATH : '') |
| }), |
| ...pages |
| ] |
| } |
| |
| module.exports = { |
| isProduction, |
| assetsDir, |
| distDir, |
| baseConfig |
| } |