0

webpack/share.js

const path = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackHarddiskPlugin = require('html-webpack-harddisk-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {
    rm
} = require('shelljs')
const pkg = require('../package.json')
const webpack = require('webpack')

const baseChunks = ['config', 'app']

const basePlugins = (chunks, enableHtml) => {
const html = enableHtml ? [
    new HtmlWebpackPlugin({
        title: 'PMR Client',
        filename: './index.html',
        template: './src/client/index.ejs',
        chunksSortMode: (a, b) => chunks.indexOf(a.names[0]) - chunks.indexOf(b.names[0]),
        alwaysWriteToDisk: true,
        env: process.env.NODE_ENV || 'development',
    }),
    new HtmlWebpackHarddiskPlugin(),
] : []
return [
    new ExtractTextPlugin('style.css'),
    ...html,
    new webpack.ProvidePlugin({
        'window.jQuery': 'jquery',
    }),
    new webpack.optimize.ModuleConcatenationPlugin(),
]
}

const baseEntries = {
app: './src/app/index.js',
config: `./clients/${process.env.CLIENT}/config.js`,
}

const baseOutput = () => {
const output = {
    path: path.join(__dirname, `../dist/cdn/${pkg.version}`),
    filename: '[name].bundle.js',
}
if (process.env.NODE_ENV === 'production' && process.env.UPLOAD === 'true') {
    output['publicPath'] = `//streamlinedoffice.com/pmr/cdn/${pkg.version}/`
}
return output
}

const sourceMap = (process.env.NODE_ENV === 'production') ? '' : 'sourceMap'

const getBaseConfig = ({
plugins = [],
chunks = [],
entries = baseEntries,
enableHtml = false
} = {}) => {
rm('-rf', path.resolve(__dirname, '../dist'))

const ch = [...baseChunks, ...chunks]
return {
    entry: entries,
    output: baseOutput(),
    target: 'web',
    devtool: 'cheap-module-eval-source-map',
    plugins: [...basePlugins(ch, enableHtml), ...plugins],
    module: {
        rules: [{
                test: /\.html$/,
                use: [{
                    loader: 'html-loader',
                    options: {
                        minimize: true,
                        root: '../src/assets/images',
                    },
                }, ],
            },
            {
                test: [/src\/app.*\.js$/, /client.*\.js$/],
                exclude: /node_modules/,
                //  use: {
                loader: 'babel-loader',
                // },
            },
            {
                test: [/\.css$/, /\.scss$/],
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', `sass-loader?${sourceMap}`],
                }),
            },
            {
                test: /bootstrap-sass\/assets\/javascripts\//,
                use: 'imports-loader?jQuery=jquery'
            },
            // Font Definitions
            {
                test: /\.svg$/,
                loader: 'url-loader?limit=65000&mimetype=image/svg+xml&name=public/fonts/[name].[ext]',
            },
            {
                test: /\.woff$/,
                loader: 'url-loader?limit=65000&mimetype=application/font-woff&name=public/fonts/[name].[ext]',
            },
            {
                test: /\.woff2$/,
                loader: 'url-loader?limit=65000&mimetype=application/font-woff2&name=public/fonts/[name].[ext]',
            },
            {
                test: /\.[ot]tf$/,
                loader: 'url-loader?limit=65000&mimetype=application/octet-stream&name=public/fonts/[name].[ext]',
            },
            {
                test: /\.eot$/,
                loader: 'url-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=public/fonts/[name].[ext]',
            },
            {
                test: /\.png$/,
                use: {
                    loader: 'url-loader?limit=8192',
                },
            },
            {
                test: /\.(jpe?g|gif)$/i,
                use: [
                    'file-loader?hash=sha512&digest=hex&publicPath=../&name=./img/[hash].[ext]',
                    {
                        loader: 'image-webpack-loader',
                        query: {
                            gifsicle: {
                                interlaced: false,
                            },
                            progressive: true,
                            optipng: {
                                optimizationLevel: 7,
                            },
                            bypassOnDebug: true,
                        },
                    },
                ],
            },
        ],
    },
}
}
module.exports = getBaseConfig

包.json

"name": "pmrdashboard",
"version": "3.2.0",
"dependencies": {
    "@cgross/angular-notify": "2.5.1",
    "@uirouter/angularjs": "~1.0.7",
    "angular": "1.4.2",
    "angular-bootstrap": "~0.12.2",
    "angular-chart.js": "^1.0.1",
    "angular-gantt": "^1.2.13",
    "angular-google-chart": "^0.1.0",
    "angular-messages": "~1.4.2",
    "angular-moment": "1.0.1",
    "angular-pubsub": "^0.2.0",
    "angular-resource": "~1.4.2",
    "angular-sanitize": "~1.4.2",
    "angular-strap": "^2.3.9",
    "angular-toastr": "~1.5.0",
    "animate.css": "~3.4.0",
    "axios": "^0.16.2",
    "babel-cli": "^6.26.0",
    "babel-core": "^6.24.1",
    "babel-polyfill": "^6.23.0",
    "babel-runtime": "^6.23.0",
    "bootstrap-sass": "3.3.7",
    "chart.js": "2.1.0",
    "deepmerge": "^1.3.2",
    "jquery": "~2.1.4",
    "jshint": "^2.9.5",
    "lodash": "^4.13.1",
    "moment": "2.10.6",
    "ngsticky-puemos": "^0.0.4",
    "node-sass": "4.5.3",
    "ramda": "^0.22.1",
    "webpack": "^3.0.0"
},
"scripts": {
    "dev": "babel-node scripts/cli.js dev",
    "serve": "babel-node scripts/cli.js serve",
    "build": "babel-node scripts/cli.js build --upload=false --plugins dynamic-import-node",
    "deploy": "babel-node scripts/cli.js build",
    "serve:prod": "babel-node scripts/cli.js serve:prod",
    "serve:optimize": "babel-node scripts/cli.js serve:prod --optimize=true",
    "serve:cdn": "babel-node scripts/cli.js serve:prod --usecdn=true"
},
"devDependencies": {
    "babel-eslint": "^7.2.3",
    "babel-loader": "^7.0.0",
    "babel-plugin-angularjs-annotate": "^0.7.0",
    "babel-plugin-dynamic-import-node": "^1.0.2",
    "babel-plugin-external-helpers": "^6.22.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
    "babel-plugin-transform-object-rest-spread": "^6.23.0",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.5.1",
    "babel-preset-es2015": "^6.24.1",
    "chalk": "^1.1.3",
    "clean-webpack-plugin": "0.1.16",
    "cross-env": "^5.1.3",
    "css-loader": "0.28.1",
    "eslint": "2.13.1",
    "eslint-config-angular": "^0.5.0",
    "eslint-plugin-angular": "^2.4.0",
    "execa": "^0.6.3",
    "exports-loader": "0.6.4",
    "express": "^4.15.3",
    "extract-text-webpack-plugin": "2.1.0",
    "file-loader": "0.11.1",
    "fs-extra": "^3.0.1",
    "html-loader": "0.4.5",
    "html-webpack-harddisk-plugin": "0.1.0",
    "html-webpack-plugin": "2.28.0",
    "http-proxy-middleware": "*",
    "http-server": "^0.10.0",
    "image-webpack-loader": "3.3.1",
    "imports-loader": "0.7.1",
    "jshint-loader": "^0.8.4",
    "raw-loader": "0.5.1",
    "resolve-url-loader": "2.0.2",
    "rollup": "^0.43.0",
    "rollup-plugin-babel": "^2.7.1",
    "rollup-plugin-node-resolve": "^3.0.0",
    "sass-loader": "6.0.5",
    "shelljs": "^0.7.7",
    "ssh-webpack-plugin": "^0.1.7",
    "style-loader": "0.17.0",
    "svg-loader": "0.0.2",
    "url-loader": "0.5.8",
    "webpack": "3.0.0",
    "webpack-dev-server": "^2.5.0",
    "yargs": "^8.0.1"
},
"engines": {
    "node": ">=0.10.0"
}

babelrc

{
  "presets": ["env"],
  "plugins": ["transform-object-rest-spread", "dynamic-import-node"]
}

控制台中的错误

ERROR in ./src/app/components/filters/filters.directive.js
Module parse failed: Unexpected token (115:4)
You may need an appropriate loader to handle this file type.
| function filtersDirective() {
|   return {
|     ...baseDirective(template, FiltersCtrl),
|     ...{
|       bindToController: {
@ ./src/app/components/index.js 36:0-58
@ ./src/app/index.js
@ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/app/index.js

*.directive.js为所有文件获取上述错误

这是 filter.directive.js

import R from 'ramda'
import {
baseDirective
} from '../../utils'
import template from './filters.directive.html'
/**
 * Returns a function to filter an array of projects based on the id
 * and the compare function
 * @param id {Int}
 * @param projects {Array}
 * @param compareFn {Function}
 * @return Function
*/
const filterBy = function(id, projects, compareFn) {
if (!R.isNil(id) && !R.isEmpty(id)) {
    return projects.filter(compareFn)
}
return projects
}

/**
* Return a curried function to filter the projects list by customer
* @param id {Int}
* @param projects {Array}
*/
const filterByCustomer = R.curry((id, projects) =>
 filterBy(id, projects, item => item.customerName.Id === parseInt(id))
)

/**
* Return a curried function to filter the projects list by Region
* @param id {Int}
* @param projects {Array}
*/
const filterByRegion = R.curry((id, projects) =>
 filterBy(id, projects, item => item.region.Id === parseInt(id))
)

/**
 * Return a curried function to filter the projects list by Manager
 * @param id {Int}
 * @param projects {Array}
*/
const filterByManager = R.curry((id, projects) =>
 filterBy(id, projects, item => item.projectManager.Id === parseInt(id))
)

/**
 * Return a curried function to filter the projects list by Status
 * @param id {Int}
 * @param projects {Array}
*/
const filterByStatus = R.curry((name, projects) =>
filterBy(name, projects, item => {
    if (name === 'All Statuses') {
        return true
    }
    return item.projectStateValue === name
})
)

function FiltersCtrl(PubSub, CurrentList) {
'ngInject'
this.statuses.unshift({
    name: 'All Statuses',
    projectId: 0,
    id: 0,
})
this.status = this.statuses[0].name
const baseProjects = CurrentList.getOriginalList()

/**
 * Apply selected filters to a list of controllers
 * use the PubSub service to publish the event and the filtered projects 
list
 */
const applyFilters = function() {
    const filterProjects = R.compose(
        filterByManager(this.manager),
        filterByRegion(this.region),
        filterByCustomer(this.customer),
        filterByStatus(this.status)
    )
    CurrentList.setFilters({
        manager: this.manager,
        region: this.region,
        customer: this.customer,
        status: this.status,
    })
    PubSub.publish('projectsFiltered', filterProjects(baseProjects))
}

const clearFilters = function() {
    PubSub.publish('projectsCleared')
}

//Get the previously existent filters
const setFilters = function() {
    const filters = CurrentList.getFilters()
    if (!R.isEmpty(filters)) {
        this.manager = CurrentList.getFilters('manager')
        this.region = CurrentList.getFilters('region')
        this.customer = CurrentList.getFilters('customer')
        this.status = CurrentList.getFilters('status')
        applyFilters.call(this)
    }
}
setFilters.call(this)

angular.extend(this, {
    applyFilters,
    clearFilters,
})
}

function filtersDirective() {
  return {
    ...baseDirective(template, FiltersCtrl), // line where the error is thrown in console
    ...{
        bindToController: {
            customers: '=',
            regions: '=',
            managers: '=',
            projects: '=',
            statuses: '=',
        },
    },
  }
}

export default filtersDirective

下面是来自 utils 的 baseDirective 的代码

import R from 'ramda'
import moment from 'moment'
import deepmerge from 'deepmerge'

// baseDirective params: template (comes from an import), controller is a 
function
// returns an object
export const baseDirective = (template, controller = function() {}) => ({
    restrict: 'EA',
    template,
    controller,
    controllerAs: 'vm',
    scope: {}
})

/**
 * Filter and array based on a string (color), returns the lengh of the new 
  array
 * @param color {String}
 * @param array {Array}
 * @return Int the lenght of the new filtered array
*/
export const filterByColor = (color, array) =>
    array.filter(item => item === color).length

export const groupByCount = (array, appendName) =>
    toLower(array).reduce((memory, item) => {
        if (item !== '') {
           if (memory.hasOwnProperty(`${item}${appendName}`)) {
                memory[`${item}${appendName}`] += 1
            } else {
                memory[`${item}${appendName}`] = 1
            }
        }
        return memory
    }, [])

/**
 * Creates a curried function that accepts an array
 * iterate over each item and convert string to lowercase
 * @param {Array}
 * @returns Function
 */
export const toLower = R.map(R.toLower)

/**
 * Return a parsed  date using moment
 */
export const getDate = date => {
    if (R.isEmpty(date) || R.isNil(date)) {
        return ''
    }
    return moment(date).utc().format('MM/DD/YYYY')
}

export const setClassName = value => {
    switch (value.toLowerCase()) {
        case 'green':
            return 'success'
        case 'red':
            return 'danger'
        case 'yellow':
            return 'warning'
    }
}

export const booleanToText = value => (value ? 'Yes' : 'No')

export const isObject = val =>
    (val !== null && val.constructor === Object) || val instanceof Object

所有指令都具有类似的结构,如 filtersDirective 和指向 baseDirective @ ./src/app/components/index.js 36:0-58 是我导入 filters.directive.js 的行(从 '. /filters/filters.directive') 所有指令都抛出相同的错误,我得到 webpack: Failed to compile
in console 关于模块解析错误的任何想法?

4

1 回答 1

-1

...baseDirective您的问题是and前面的所有这些点...{。那些是干什么用的?这不是有效的 JavaScript。

function filtersDirective() {
  return {
    ...baseDirective(template, FiltersCtrl), // line where the error is thrown in console
    ...{
        bindToController: {
            customers: '=',
            regions: '=',
            managers: '=',
            projects: '=',
            statuses: '=',
        },
    },
  }
}
于 2018-01-26T14:59:15.610 回答