├── .gitignore
├── template
├── page.js
├── src
│ ├── common
│ │ ├── icons
│ │ │ ├── index.js
│ │ │ └── face.js
│ │ ├── style
│ │ │ ├── common.scss
│ │ │ └── svg.css
│ │ ├── assets
│ │ │ └── test.png
│ │ ├── util
│ │ │ └── message.js
│ │ ├── components
│ │ │ └── Dialog.vue
│ │ └── svg
│ │ │ └── face.svg
│ └── view
│ │ └── index
│ │ ├── styles
│ │ ├── index.css
│ │ └── test.scss
│ │ ├── assets
│ │ └── turn-pointer.png
│ │ ├── components
│ │ ├── Shape.vue
│ │ └── App.vue
│ │ ├── main.js
│ │ └── template.html
├── .babelrc
├── .gitignore
├── build
│ ├── vue-loader.config.js
│ ├── dev-client.js
│ ├── config.js
│ ├── server.js
│ ├── webpack.dev.js
│ ├── webpack.base.js
│ ├── css-loaders.js
│ ├── webpack.prod.js
│ └── webpack.dll.js
├── gulpfile.js
├── README.md
├── package.json
└── lib
│ └── zepto.min.js
├── meta.json
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/template/page.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 需要构建的页面 一次只构建一个页面
3 | */
4 | module.exports = 'index'
--------------------------------------------------------------------------------
/template/src/common/icons/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('./face')
3 |
--------------------------------------------------------------------------------
/template/src/common/style/common.scss:
--------------------------------------------------------------------------------
1 | .color {
2 | transform: rotate(45deg);
3 | display: flex;
4 | }
--------------------------------------------------------------------------------
/template/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [["es2015", { "modules": false }], "stage-2"],
3 | "comments": false
4 | }
5 |
--------------------------------------------------------------------------------
/template/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log
4 | .idea
5 | manifest.json
6 | dist
7 | lib/vendor
--------------------------------------------------------------------------------
/template/src/view/index/styles/index.css:
--------------------------------------------------------------------------------
1 | .header {
2 | color: red;
3 | transition: all .3s ease;
4 | display: flex;
5 | }
--------------------------------------------------------------------------------
/template/src/common/assets/test.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agileago/webpack-mutiple/HEAD/template/src/common/assets/test.png
--------------------------------------------------------------------------------
/template/src/view/index/assets/turn-pointer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agileago/webpack-mutiple/HEAD/template/src/view/index/assets/turn-pointer.png
--------------------------------------------------------------------------------
/template/src/common/util/message.js:
--------------------------------------------------------------------------------
1 | export function show () {
2 | console.log('i am show')
3 | }
4 |
5 | export function bar () {
6 | console.log('i am bar')
7 | }
--------------------------------------------------------------------------------
/template/build/vue-loader.config.js:
--------------------------------------------------------------------------------
1 | const page = require('./config')
2 |
3 | module.exports = {
4 | postcss: [require('autoprefixer')({ browsers: page.browsers })],
5 | loaders: {
6 | scss: 'vue-style-loader!css-loader!sass-loader'
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/template/build/dev-client.js:
--------------------------------------------------------------------------------
1 | require('eventsource-polyfill')
2 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
3 |
4 | hotClient.subscribe(function (event) {
5 | if (event.action === 'reload') {
6 | window.location.reload()
7 | }
8 | })
--------------------------------------------------------------------------------
/template/src/view/index/styles/test.scss:
--------------------------------------------------------------------------------
1 | .header {
2 | animation: bling 2s ease both;
3 |
4 | @at-root {
5 | @keyframes bling {
6 | 0% {
7 | opacity: 0;
8 | color: red;
9 | }
10 | 100% {
11 | opacity: 1;
12 | color: green;
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/template/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp')
2 | var revHash = require('gulp-rev-hash3')
3 |
4 | gulp.task('rev-hash', function () {
5 | return gulp.src(`dist/**/index.html`)
6 | .pipe(revHash({
7 | assetsDir: 'dist',
8 | projectPath: './'
9 | }))
10 | .pipe(gulp.dest(`dist`))
11 | })
12 |
13 | gulp.task('default', ['rev-hash'])
--------------------------------------------------------------------------------
/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "schema": {
3 | "name": {
4 | "type": "string",
5 | "required": true,
6 | "label": "Project name"
7 | },
8 | "description": {
9 | "type": "string",
10 | "required": false,
11 | "label": "Project description",
12 | "default": "A Vue.js project"
13 | },
14 | "author": {
15 | "type": "string",
16 | "label": "Author"
17 | }
18 | },
19 | "skipInterpolation": "src/**/*.vue"
20 | }
21 |
--------------------------------------------------------------------------------
/template/src/common/style/svg.css:
--------------------------------------------------------------------------------
1 | .svg-icon {
2 | display: inline-block;
3 | width: 1em;
4 | height: 1em;
5 | color: inherit;
6 | vertical-align: middle;
7 | fill: none;
8 | stroke: currentColor;
9 | }
10 |
11 | .svg-fill {
12 | fill: currentColor;
13 | stroke: none;
14 | }
15 |
16 | .svg-up {
17 | transform: rotate(-90deg);
18 | }
19 |
20 | .svg-right {
21 | /*default*/
22 | transform: rotate(0deg);
23 | }
24 |
25 | .svg-down {
26 | transform: rotate(90deg);
27 | }
28 |
29 | .svg-left {
30 | transform: rotate(180deg);
31 | }
--------------------------------------------------------------------------------
/template/src/view/index/components/Shape.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ msg }}
4 |
5 |
6 |
7 |
16 |
17 |
--------------------------------------------------------------------------------
/template/src/view/index/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | require('es6-promise').polyfill()
3 | import 'weui'
4 | import App from './components/App.vue'
5 | import { ToastPlugin } from 'vux'
6 | import * as svgicon from 'vue-svgicon'
7 | import '../../common/style/svg.css'
8 | import '../../common/icons'
9 |
10 | Vue.use(svgicon, {
11 | tagname: 'svgicon',
12 | defaultWidth: '1.2em',
13 | defaultHeight: '1.2em'
14 | })
15 |
16 | Vue.use(ToastPlugin)
17 |
18 | Vue.config.devtools = true
19 |
20 | window.$message = function (text) {
21 | Vue.$vux.toast.show({ text, type: 'text' })
22 | }
23 |
24 | new Vue({
25 | el: '#app',
26 | render: h => h(App)
27 | })
28 |
29 |
--------------------------------------------------------------------------------
/template/build/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 需要构建的页面 一次只构建一个页面
3 | */
4 | const pageName = require('../page')
5 |
6 | const notUseVendor = [] // 不使用公共资源的页面集合
7 | const notExtractCss = [] // 不抽取css的页面
8 | const useAbsolutePath = { // 使用绝对路径的页面
9 | example: '//cdn.com/'
10 | }
11 |
12 | module.exports = {
13 | pageName: pageName,
14 | useVendor: notUseVendor.indexOf(pageName) === -1, // 是否使用公共资源 需要先运行 np run vendor
15 | sourceMap: false, // 生产环境下是否需要js生成sourceMap
16 | extractCss: notExtractCss.indexOf(pageName) === -1, // 是否抽取出css
17 | // 资源引用路径是否为绝对路径 默认为相对路径
18 | // cdn 地址 绝对路径的地址 如果没有cdn域名请填写 / 默认是相对路径 false
19 | absolutePath: useAbsolutePath[pageName] == undefined ? false : useAbsolutePath[pageName],
20 | browsers: ['ios > 7', 'android > 4.1']
21 | }
--------------------------------------------------------------------------------
/template/src/view/index/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | index
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/template/src/common/icons/face.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | var icon = require('vue-svgicon')
4 | icon.register({
5 | 'face': {
6 | width: 200,
7 | height: 200,
8 | viewBox: '0 0 1024 1024',
9 | data: ``
10 | }
11 | })
12 |
--------------------------------------------------------------------------------
/template/build/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const webpack = require('webpack')
3 | const config = require('./webpack.dev.js')
4 |
5 | const app = express()
6 | const compiler = webpack(config)
7 |
8 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
9 | publicPath: config.output.publicPath,
10 | // stats: {
11 | // colors: true,
12 | // chunks: false,
13 | // children: false,
14 | // chunks: false,
15 | // chunkModules: false
16 | // }
17 | log: false,
18 | heartbeat: 2000
19 | })
20 | var hotMiddleware = require('webpack-hot-middleware')(compiler)
21 | compiler.plugin('compilation', function (compilation) {
22 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
23 | // console.log(data)
24 | // hotMiddleware.publish({ action: 'reload' })
25 | cb()
26 | })
27 | })
28 |
29 | app.use(require('connect-history-api-fallback')())
30 | app.use(devMiddleware)
31 | app.use(hotMiddleware)
32 | // serve pure static assets
33 | app.use('/lib', express.static('./lib'))
34 | // mobile visit in one wifi
35 | app.listen(8080, '0.0.0.0', function (err) {
36 | if (err) {
37 | console.log(err)
38 | return
39 | }
40 | console.log('Listening at http://localhost:8080')
41 | })
42 |
--------------------------------------------------------------------------------
/template/README.md:
--------------------------------------------------------------------------------
1 | ### 多页面vue2/webpack2构建配置
2 |
3 | 使用vue来写一些单页面很舒服,官方也有很健全的配置starter,但一般在业务生产中都不可能是单页面,往往需要做很多页面,需要
4 | 多人来配合来写,这个时候就需要进行项目的工程化,特别是针对前后端分离的项目,后端只提供json格式的数据,前端负责渲染页面和各种
5 | 路由处理,所以需要一个多页面的配置来进行开发指导,这个项目需要是实现的功能如下:
6 |
7 | 1. 使用ES6(并且使用webpack2的tree-shaking功能进行缩减代码)
8 | 2. 组件化`*.vue`开发
9 | 3. 功能模块化
10 | 4. 静态资源压缩
11 | 5. 静态资源破缓存(url?hash)(`gulp + webpack`实现)
12 | 6. 开发环境下页面自动刷新或者热替换
13 | 7. 支持多页面
14 | 8. 公共资源缓存(`vendor`)
15 | 9. css去重(由`vux-loader实现`)
16 | 10. 支持vue的jsx写法
17 |
18 | #### 项目说明
19 | > -- page.js 编译页面配置(团队项目请把此文件加入.gitignore里面禁止提交此文件)
20 |
21 | > -- build 构建文件存放
22 |
23 | > -- dist 输出目录 把此文件放入cdn或者给后端
24 |
25 | >-- lib 全局使用的外部库
26 |
27 | >-- src 业务源代码
28 | >---- common 页面公共组件
29 | >---- view 页面源码 每个页面是个单独的文件夹 所使用的图片等资源在每个页面的文件夹里面
30 |
31 |
32 | ### 使用说明
33 | 团队里面每个人在开始开发页面之前,需要在`page.js`配置一下需要开发的页面
34 |
35 | ### 首先打包公共资源vendor, 公共资源配置在 `package.json`中,统一管理
36 | ```
37 | npm run vendor
38 | ```
39 | 如果生成的有css文件模块,需要在`manifest.json`文件里面把`css`模块的meta重写成{},不然最终编译后会带有css文件
40 |
41 | 开发环境下使用
42 | ```bash
43 | npm run dev
44 | ```
45 | 命令进行开发,在浏览器里面打开[0.0.0.0:8080](http://0.0.0.0:8080),已配置自动刷新和热替换
46 |
47 | 开发完成后使用
48 | ```bash
49 | npm run build
50 | ```
51 | 命令进行打包 `dist`文件夹里面即是最终的发布文件
--------------------------------------------------------------------------------
/template/build/webpack.dev.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack')
2 | var config = require('./webpack.base.js')
3 | var cssLoaders = require('./css-loaders')
4 | var HtmlWebpackPlugin = require('html-webpack-plugin')
5 | var page = require('./config')
6 | var vueConfig = require('./vue-loader.config')
7 | var path = require('path')
8 | var vuxLoader = require('vux-loader')
9 |
10 | config.devtool = 'source-map'
11 | cssLoaders({ sourceMap: false, extract: false }).forEach(function (loader) {
12 | config.module.rules.push({
13 | test: new RegExp('\\.' + loader.key + '$'),
14 | loader: loader.value
15 | })
16 | })
17 |
18 | config.entry.app = ['./build/dev-client', config.entry.app]
19 | config.output.publicPath = '/'
20 | config.plugins = config.plugins.concat([
21 | new webpack.DefinePlugin({
22 | 'process.env.NODE_ENV': JSON.stringify('development')
23 | }),
24 | new webpack.HotModuleReplacementPlugin(),
25 | new webpack.NoEmitOnErrorsPlugin(),
26 | new webpack.LoaderOptionsPlugin({
27 | options: {
28 | context: path.resolve(__dirname, '../'),
29 | postcss: [require('autoprefixer')({ browsers: page.browsers })]
30 | }
31 | }),
32 | new HtmlWebpackPlugin({
33 | filename: 'index.html',
34 | template: page.template,
35 | inject: true,
36 | path: '/'
37 | })
38 | ])
39 |
40 | // module.exports = config
41 |
42 | module.exports = vuxLoader.merge(config, { plugins: ['vux-ui'], showVuxVersionInfo: false })
--------------------------------------------------------------------------------
/template/build/webpack.base.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const page = require('./config')
4 | const vueConfig = require('./vue-loader.config')
5 |
6 | process.env.BROWSERSLIST = page.browsers
7 |
8 | page.entry = { app: path.resolve(__dirname, '../src/view/' + page.pageName + '/main.js') }
9 | page.template = path.resolve(__dirname, '../src/view/' + page.pageName + '/template.html')
10 |
11 | module.exports = {
12 | entry: page.entry,
13 | output: {
14 | path: path.resolve(__dirname, '../dist/' + page.pageName + '/static'),
15 | publicPath: page.absolutePath ? page.absolutePath + page.pageName + '/static/' : './static/',
16 | filename: '[name].js'
17 | },
18 | resolve: {
19 | extensions: ['.js', '.json', '.vue']
20 | },
21 | module: {
22 | rules: [
23 | {
24 | test: /\.vue$/,
25 | loader: 'vue-loader',
26 | options: vueConfig
27 | },
28 | {
29 | test: /\.js$/,
30 | loader: 'babel-loader',
31 | exclude: /node_modules/
32 | },
33 | {
34 | test: /\.(png|jpg|gif|svg)$/,
35 | loader: 'url-loader',
36 | options: {
37 | limit: 8000,
38 | name: '[name].[ext]?[hash:7]'
39 | }
40 | }
41 | ]
42 | },
43 | plugins: [
44 | new webpack.HashedModuleIdsPlugin()
45 | ],
46 | node: { // to fix css-loader add node-shim
47 | Buffer: false
48 | }
49 | }
50 |
51 | if (page.useVendor) {
52 | module.exports.plugins.push(new webpack.DllReferencePlugin({
53 | context: __dirname,
54 | manifest: require('../manifest.json')
55 | }))
56 | }
--------------------------------------------------------------------------------
/template/build/css-loaders.js:
--------------------------------------------------------------------------------
1 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
2 | const page = require('./config')
3 |
4 | module.exports = function (options) {
5 | // generate loader string to be used with extract text plugin
6 | function generateLoaders (loaders) {
7 | var sourceLoader = loaders.map(function (loader) {
8 | var extraParamChar
9 | if (/\?/.test(loader)) {
10 | loader = loader.replace(/\?/, '-loader?')
11 | extraParamChar = '&'
12 | } else {
13 | loader = loader + '-loader'
14 | extraParamChar = '?'
15 | }
16 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
17 | }).join('!')
18 |
19 | if (options.extract) {
20 | // override publicPath
21 | return ExtractTextPlugin.extract({
22 | fallback: 'style-loader',
23 | use: sourceLoader,
24 | publicPath: page.absolutePath ? undefined : './'
25 | })
26 | } else {
27 | return ['style-loader', sourceLoader].join('!')
28 | }
29 | }
30 |
31 | // http://vuejs.github.io/vue-loader/configurations/extract-css.html
32 | return [
33 | {
34 | key: 'css',
35 | value: generateLoaders(['css', 'postcss'])
36 | },
37 | {
38 | key: 'less',
39 | value: generateLoaders(['css', 'postcss', 'less'])
40 | },
41 | {
42 | key: 'sass',
43 | value: generateLoaders(['css', 'postcss', 'sass'])
44 | },
45 | {
46 | key: 'scss',
47 | value: generateLoaders(['css', 'postcss', 'sass'])
48 | },
49 | {
50 | key: 'stylus',
51 | value: generateLoaders(['css', 'postcss', 'stylus'])
52 | },
53 | {
54 | key: 'styl',
55 | value: generateLoaders(['css', 'postcss', 'stylus'])
56 | }
57 | ]
58 | }
59 |
--------------------------------------------------------------------------------
/template/src/common/components/Dialog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | 标题
9 |
10 |
11 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
28 |
29 |
--------------------------------------------------------------------------------
/template/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-mutiple",
3 | "description": "A Vue.js project",
4 | "author": "agileago ",
5 | "version": "0.0.1",
6 | "private": true,
7 | "vendor": [
8 | "animejs",
9 | "vue",
10 | "es6-promise",
11 | "weui"
12 | ],
13 | "scripts": {
14 | "dev": "node build/server.js",
15 | "build": "webpack --hide-modules --config build/webpack.prod.js && ncp lib dist/lib && gulp",
16 | "vendor": "rm -rf lib/vendor && webpack --config build/webpack.dll.js",
17 | "cplib": "ncp lib dist/lib",
18 | "svg": "vsvg -s ./src/common/svg/ -t ./src/common/icons/"
19 | },
20 | "dependencies": {
21 | "animejs": "^2.0.2",
22 | "es6-promise": "^4.1.1",
23 | "vue": "^2.4.2",
24 | "vue-svgicon": "^2.1.0",
25 | "vux": "^2.5.3",
26 | "weui": "^1.1.2"
27 | },
28 | "devDependencies": {
29 | "autoprefixer": "^6.7.7",
30 | "babel-core": "^6.25.0",
31 | "babel-loader": "^7.1.1",
32 | "babel-preset-es2015": "^6.24.1",
33 | "babel-preset-stage-2": "^6.24.1",
34 | "connect-history-api-fallback": "^1.3.0",
35 | "css-loader": "^0.28.4",
36 | "eventsource-polyfill": "^0.9.6",
37 | "express": "^4.15.3",
38 | "extract-text-webpack-plugin": "^3.0.0",
39 | "file-loader": "^0.11.2",
40 | "gulp": "^3.9.1",
41 | "gulp-rev-hash3": "^1.0.9",
42 | "html-webpack-plugin": "^2.29.0",
43 | "less": "^2.7.2",
44 | "less-loader": "^4.0.5",
45 | "ncp": "^2.0.0",
46 | "postcss-loader": "^1.3.3",
47 | "rimraf": "^2.6.1",
48 | "style-loader": "^0.18.2",
49 | "url-loader": "^0.5.9",
50 | "vue-loader": "^12.2.2",
51 | "vue-template-compiler": "^2.4.2",
52 | "vux-loader": "^1.1.2",
53 | "webpack": "^3.3.0",
54 | "webpack-dev-middleware": "^1.11.0",
55 | "webpack-hot-middleware": "^2.18.2"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/template/src/common/svg/face.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/template/build/webpack.prod.js:
--------------------------------------------------------------------------------
1 | process.env.NODE_ENV = 'production'
2 |
3 | var webpack = require('webpack')
4 | var config = require('./webpack.base.js')
5 | var cssLoaders = require('./css-loaders')
6 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
7 | var HtmlWebpackPlugin = require('html-webpack-plugin')
8 | var page = require('./config')
9 | var rimraf = require('rimraf')
10 | var path = require('path')
11 | var vueConfig = require('./vue-loader.config')
12 | var vuxLoader = require('vux-loader')
13 |
14 | config.output.filename = '[name].js'
15 | config.output.chunkFilename = '[id].js?[chunkhash:7]'
16 | config.devtool = page.sourceMap ? 'source-map' : false
17 |
18 | vueConfig.loaders = vueConfig.loaders || {}
19 | cssLoaders({ sourceMap: false, extract: page.extractCss }).forEach(function (loader) {
20 | if (page.extractCss) {
21 | vueConfig.loaders[loader.key] = loader.value
22 | }
23 | config.module.rules.push({
24 | test: new RegExp('\\.' + loader.key + '$'),
25 | loader: loader.value
26 | })
27 | })
28 |
29 | if (page.extractCss) {
30 | config.plugins.push(new ExtractTextPlugin('[name].css'))
31 | }
32 |
33 | config.plugins = config.plugins.concat([
34 | new webpack.DefinePlugin({
35 | 'process.env.NODE_ENV': JSON.stringify('production')
36 | }),
37 | new webpack.LoaderOptionsPlugin({
38 | minimize: true,
39 | options: {
40 | context: path.resolve(__dirname, '../'),
41 | postcss: [require('autoprefixer')({ browsers: page.browsers })]
42 | }
43 | }),
44 | new webpack.optimize.UglifyJsPlugin({
45 | sourceMap: page.sourceMap,
46 | compress: {
47 | warnings: false
48 | }
49 | }),
50 | new HtmlWebpackPlugin({
51 | filename: '../index.html',
52 | template: page.template,
53 | inject: true,
54 | hash: true,
55 | path: page.absolutePath ? page.absolutePath : '../'
56 | })
57 | ])
58 |
59 | rimraf.sync(path.resolve(__dirname, '../dist/' + page.pageName))
60 |
61 | module.exports = vuxLoader.merge(config, { plugins: ['vux-ui', 'duplicate-style'] })
62 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # webpack-mutiple
2 | ### vue多页面开发脚手架
3 |
4 | vue官方只提供了单页面的脚手架,但我们可以根据它来改造成多页面,开发的时候我们每次只开发一个页面,而不是同时开发多个页面,所以项目根路径下应该有个配置js,来指明这次要开发的页面
5 |
6 | ### 工具推荐
7 | 1. 最新版webstorm
8 | 2. 使用[yarn](https://yarnpkg.com/)安装依赖(提供lock功能) 国内用户请使用淘宝源
9 | `yarn config set registry https://registry.npm.taobao.org`
10 | 3. node-sass安装失败解决方案
11 | `SASS_BINARY_SITE=https://npm.taobao.org/mirrors/node-sass/ npm install node-sass`
12 |
13 | ### 使用
14 |
15 | 这是一个[vue-cli](https://github.com/vuejs/vue-cli).的项目模板
16 |
17 | ``` bash
18 | $ npm install -g vue-cli
19 | $ vue init agileago/webpack-mutiple my-project
20 | $ cd my-project
21 | $ npm install (或者 yarn)
22 | $ npm run vendor
23 | $ npm run dev
24 | $ npm run build
25 | ```
26 |
27 | ### 多页面如何配置
28 |
29 | 配置在`config.js`里面
30 |
31 |
32 | ``` javascript
33 | /**
34 | * 需要构建的页面 一次只构建一个页面
35 | */
36 | const pageName = 'index'
37 |
38 | // 大部分情况下都是默认配置
39 |
40 | const notUseVendor = [] // 不使用公共资源的页面集合
41 | const notExtractCss = [] // 不抽取css的页面
42 | const useAbsolutePath = { // 使用绝对路径的页面
43 | example: '//cdn.com/'
44 | }
45 |
46 | module.exports = {
47 | pageName: pageName,
48 | useVendor: notUseVendor.indexOf(pageName) === -1, // 是否使用公共资源 需要先运行 np run vendor
49 | extractCss: notExtractCss.indexOf(pageName) === -1, // 是否抽取出css
50 | // 资源引用路径是否为绝对路径 默认为相对路径
51 | // cdn 地址 绝对路径的地址 如果没有cdn域名请填写 / 默认是相对路径 false
52 | absolutePath: useAbsolutePath[pageName] == undefined ? false : useAbsolutePath[pageName],
53 | sourceMap: false, // 生产环境下是否需要js生成sourceMap
54 | browsers: ['ios > 7', 'android > 4.1']
55 | }
56 | ```
57 |
58 | ### 公共资源 vendor
59 | 多个页面需要共享资源库,利用webpack的dll功能生成vendor, vendor的配置在 `package.json`中的`vendor`选项
60 |
61 | ``` json
62 | "vendor": [
63 | "vue",
64 | "es6-promise",
65 | "weui"
66 | ],
67 | ```
68 |
69 | ### 生成页面
70 | 每做一个新页面需要在`src/views/`下面生成一个页面文件夹,文件夹里面需要包含一个入口文件 `main.js` 和页面模板文件 `template.html`,具体请看`index`示例页面
71 |
72 | ### tips
73 |
74 | 当想在工程里面引入`node_modules`下工程某些源代码,但这些源代码有可能是es6语法的,可直接在webpack的
75 | loader里面添加
76 | ```javascript
77 | {
78 | test: /vux.src.*?js$/,
79 | loader: 'babel-loader'
80 | }
81 | ```
82 | 就是模块名 . 源码文件夹 js文件
83 |
--------------------------------------------------------------------------------
/template/build/webpack.dll.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 | var page = require('./config')
5 | var cssLoaders = require('./css-loaders')
6 | var vueConfig = require('./vue-loader.config')
7 | var vendor = require('../package.json').vendor
8 |
9 | const config = {
10 | entry: {
11 | vendor: vendor
12 | },
13 | output: {
14 | path: path.resolve(__dirname, '../lib/vendor'),
15 | filename: '[name].common.js',
16 | library: '[name]_common'
17 | },
18 | plugins: [
19 | new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }),
20 | new webpack.DllPlugin({
21 | path: path.resolve(__dirname, '../manifest.json'),
22 | name: '[name]_common',
23 | context: __dirname
24 | }),
25 | new ExtractTextPlugin('[name].common.css'),
26 | new webpack.LoaderOptionsPlugin({
27 | minimize: true,
28 | options: {
29 | context: path.resolve(__dirname, '../'),
30 | postcss: [require('autoprefixer')({ browsers: page.browsers })]
31 | }
32 | }),
33 | new webpack.optimize.UglifyJsPlugin({
34 | sourceMap: false,
35 | compress: {
36 | warnings: false
37 | }
38 | }),
39 | new webpack.HashedModuleIdsPlugin()
40 | ],
41 | module: {
42 | rules: [
43 | {
44 | test: /\.vue$/,
45 | loader: 'vue-loader',
46 | options: vueConfig
47 | },
48 | {
49 | test: /\.js$/,
50 | loader: 'babel-loader',
51 | exclude: /node_modules/
52 | },
53 | {
54 | test: /\.(png|jpg|gif|svg)$/,
55 | loader: 'url-loader',
56 | options: {
57 | limit: 8000,
58 | name: '[name].[ext]?[hash:7]'
59 | }
60 | }
61 | ]
62 | },
63 | node: {
64 | Buffer: false
65 | }
66 | }
67 |
68 | // 注入cssloader
69 | vueConfig.loaders = vueConfig.loaders || {}
70 | cssLoaders({ sourceMap: false , extract: true }).forEach(function (loader) {
71 | vueConfig.loaders[loader.key] = loader.value
72 | config.module.rules.push({
73 | test: new RegExp('\\.' + loader.key + '$'),
74 | loader: loader.value
75 | })
76 | })
77 |
78 | module.exports = config
--------------------------------------------------------------------------------
/template/src/view/index/components/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
特点
5 |
6 |
svg图标解决方案
7 |
8 |
9 |
10 |
插入图片
11 |
12 |
背景图片
13 |
14 |
自动填充css前缀
15 |
16 |
异步加载
17 |
18 |
19 |
flex布局
20 |
21 |
22 |
23 |
24 |
25 |
46 |
47 |
--------------------------------------------------------------------------------
/template/lib/zepto.min.js:
--------------------------------------------------------------------------------
1 | /*! Zepto 1.1.6 (generated with Zepto Builder) - zepto event ajax form deferred callbacks - zeptojs.com/license */
2 | var Zepto=function(){function t(t){return null==t?String(t):J[X.call(t)]||"object"}function e(e){return"function"==t(e)}function n(t){return null!=t&&t==t.window}function r(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE}function i(e){return"object"==t(e)}function o(t){return i(t)&&!n(t)&&Object.getPrototypeOf(t)==Object.prototype}function s(t){return"number"==typeof t.length}function a(t){return A.call(t,function(t){return null!=t})}function u(t){return t.length>0?T.fn.concat.apply([],t):t}function c(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase()}function l(t){return t in Z?Z[t]:Z[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function f(t,e){return"number"!=typeof e||$[c(t)]?e:e+"px"}function h(t){var e,n;return L[t]||(e=D.createElement(t),D.body.appendChild(e),n=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==n&&(n="block"),L[t]=n),L[t]}function p(t){return"children"in t?k.call(t.children):T.map(t.childNodes,function(t){return 1==t.nodeType?t:void 0})}function d(t,e){var n,r=t?t.length:0;for(n=0;r>n;n++)this[n]=t[n];this.length=r,this.selector=e||""}function m(t,e,n){for(j in e)n&&(o(e[j])||Q(e[j]))?(o(e[j])&&!o(t[j])&&(t[j]={}),Q(e[j])&&!Q(t[j])&&(t[j]=[]),m(t[j],e[j],n)):e[j]!==E&&(t[j]=e[j])}function g(t,e){return null==e?T(t):T(t).filter(e)}function v(t,n,r,i){return e(n)?n.call(t,r,i):n}function y(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function b(t,e){var n=t.className||"",r=n&&n.baseVal!==E;return e===E?r?n.baseVal:n:void(r?n.baseVal=e:t.className=e)}function x(t){try{return t?"true"==t||("false"==t?!1:"null"==t?null:+t+""==t?+t:/^[\[\{]/.test(t)?T.parseJSON(t):t):t}catch(e){return t}}function w(t,e){e(t);for(var n=0,r=t.childNodes.length;r>n;n++)w(t.childNodes[n],e)}var E,j,T,C,S,N,O=[],P=O.concat,A=O.filter,k=O.slice,D=window.document,L={},Z={},$={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},F=/^\s*<(\w+|!)[^>]*>/,M=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,R=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,q=/^(?:body|html)$/i,z=/([A-Z])/g,W=["val","css","html","text","data","width","height","offset"],H=["after","prepend","before","append"],I=D.createElement("table"),_=D.createElement("tr"),B={tr:D.createElement("tbody"),tbody:I,thead:I,tfoot:I,td:_,th:_,"*":D.createElement("div")},V=/complete|loaded|interactive/,U=/^[\w-]*$/,J={},X=J.toString,Y={},G=D.createElement("div"),K={tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},Q=Array.isArray||function(t){return t instanceof Array};return Y.matches=function(t,e){if(!e||!t||1!==t.nodeType)return!1;var n=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(n)return n.call(t,e);var r,i=t.parentNode,o=!i;return o&&(i=G).appendChild(t),r=~Y.qsa(i,e).indexOf(t),o&&G.removeChild(t),r},S=function(t){return t.replace(/-+(.)?/g,function(t,e){return e?e.toUpperCase():""})},N=function(t){return A.call(t,function(e,n){return t.indexOf(e)==n})},Y.fragment=function(t,e,n){var r,i,s;return M.test(t)&&(r=T(D.createElement(RegExp.$1))),r||(t.replace&&(t=t.replace(R,"<$1>$2>")),e===E&&(e=F.test(t)&&RegExp.$1),e in B||(e="*"),s=B[e],s.innerHTML=""+t,r=T.each(k.call(s.childNodes),function(){s.removeChild(this)})),o(n)&&(i=T(r),T.each(n,function(t,e){W.indexOf(t)>-1?i[t](e):i.attr(t,e)})),r},Y.Z=function(t,e){return new d(t,e)},Y.isZ=function(t){return t instanceof Y.Z},Y.init=function(t,n){var r;if(!t)return Y.Z();if("string"==typeof t)if(t=t.trim(),"<"==t[0]&&F.test(t))r=Y.fragment(t,RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(D,t)}else{if(e(t))return T(D).ready(t);if(Y.isZ(t))return t;if(Q(t))r=a(t);else if(i(t))r=[t],t=null;else if(F.test(t))r=Y.fragment(t.trim(),RegExp.$1,n),t=null;else{if(n!==E)return T(n).find(t);r=Y.qsa(D,t)}}return Y.Z(r,t)},T=function(t,e){return Y.init(t,e)},T.extend=function(t){var e,n=k.call(arguments,1);return"boolean"==typeof t&&(e=t,t=n.shift()),n.forEach(function(n){m(t,n,e)}),t},Y.qsa=function(t,e){var n,r="#"==e[0],i=!r&&"."==e[0],o=r||i?e.slice(1):e,s=U.test(o);return t.getElementById&&s&&r?(n=t.getElementById(o))?[n]:[]:1!==t.nodeType&&9!==t.nodeType&&11!==t.nodeType?[]:k.call(s&&!r&&t.getElementsByClassName?i?t.getElementsByClassName(o):t.getElementsByTagName(e):t.querySelectorAll(e))},T.contains=D.documentElement.contains?function(t,e){return t!==e&&t.contains(e)}:function(t,e){for(;e&&(e=e.parentNode);)if(e===t)return!0;return!1},T.type=t,T.isFunction=e,T.isWindow=n,T.isArray=Q,T.isPlainObject=o,T.isEmptyObject=function(t){var e;for(e in t)return!1;return!0},T.inArray=function(t,e,n){return O.indexOf.call(e,t,n)},T.camelCase=S,T.trim=function(t){return null==t?"":String.prototype.trim.call(t)},T.uuid=0,T.support={},T.expr={},T.noop=function(){},T.map=function(t,e){var n,r,i,o=[];if(s(t))for(r=0;r=0?t:t+this.length]},toArray:function(){return this.get()},size:function(){return this.length},remove:function(){return this.each(function(){null!=this.parentNode&&this.parentNode.removeChild(this)})},each:function(t){return O.every.call(this,function(e,n){return t.call(e,n,e)!==!1}),this},filter:function(t){return e(t)?this.not(this.not(t)):T(A.call(this,function(e){return Y.matches(e,t)}))},add:function(t,e){return T(N(this.concat(T(t,e))))},is:function(t){return this.length>0&&Y.matches(this[0],t)},not:function(t){var n=[];if(e(t)&&t.call!==E)this.each(function(e){t.call(this,e)||n.push(this)});else{var r="string"==typeof t?this.filter(t):s(t)&&e(t.item)?k.call(t):T(t);this.forEach(function(t){r.indexOf(t)<0&&n.push(t)})}return T(n)},has:function(t){return this.filter(function(){return i(t)?T.contains(this,t):T(this).find(t).size()})},eq:function(t){return-1===t?this.slice(t):this.slice(t,+t+1)},first:function(){var t=this[0];return t&&!i(t)?t:T(t)},last:function(){var t=this[this.length-1];return t&&!i(t)?t:T(t)},find:function(t){var e,n=this;return e=t?"object"==typeof t?T(t).filter(function(){var t=this;return O.some.call(n,function(e){return T.contains(e,t)})}):1==this.length?T(Y.qsa(this[0],t)):this.map(function(){return Y.qsa(this,t)}):T()},closest:function(t,e){var n=this[0],i=!1;for("object"==typeof t&&(i=T(t));n&&!(i?i.indexOf(n)>=0:Y.matches(n,t));)n=n!==e&&!r(n)&&n.parentNode;return T(n)},parents:function(t){for(var e=[],n=this;n.length>0;)n=T.map(n,function(t){return(t=t.parentNode)&&!r(t)&&e.indexOf(t)<0?(e.push(t),t):void 0});return g(e,t)},parent:function(t){return g(N(this.pluck("parentNode")),t)},children:function(t){return g(this.map(function(){return p(this)}),t)},contents:function(){return this.map(function(){return this.contentDocument||k.call(this.childNodes)})},siblings:function(t){return g(this.map(function(t,e){return A.call(p(e.parentNode),function(t){return t!==e})}),t)},empty:function(){return this.each(function(){this.innerHTML=""})},pluck:function(t){return T.map(this,function(e){return e[t]})},show:function(){return this.each(function(){"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=h(this.nodeName))})},replaceWith:function(t){return this.before(t).remove()},wrap:function(t){var n=e(t);if(this[0]&&!n)var r=T(t).get(0),i=r.parentNode||this.length>1;return this.each(function(e){T(this).wrapAll(n?t.call(this,e):i?r.cloneNode(!0):r)})},wrapAll:function(t){if(this[0]){T(this[0]).before(t=T(t));for(var e;(e=t.children()).length;)t=e.first();T(t).append(this)}return this},wrapInner:function(t){var n=e(t);return this.each(function(e){var r=T(this),i=r.contents(),o=n?t.call(this,e):t;i.length?i.wrapAll(o):r.append(o)})},unwrap:function(){return this.parent().each(function(){T(this).replaceWith(T(this).children())}),this},clone:function(){return this.map(function(){return this.cloneNode(!0)})},hide:function(){return this.css("display","none")},toggle:function(t){return this.each(function(){var e=T(this);(t===E?"none"==e.css("display"):t)?e.show():e.hide()})},prev:function(t){return T(this.pluck("previousElementSibling")).filter(t||"*")},next:function(t){return T(this.pluck("nextElementSibling")).filter(t||"*")},html:function(t){return 0 in arguments?this.each(function(e){var n=this.innerHTML;T(this).empty().append(v(this,t,e,n))}):0 in this?this[0].innerHTML:null},text:function(t){return 0 in arguments?this.each(function(e){var n=v(this,t,e,this.textContent);this.textContent=null==n?"":""+n}):0 in this?this.pluck("textContent").join(""):null},attr:function(t,e){var n;return"string"!=typeof t||1 in arguments?this.each(function(n){if(1===this.nodeType)if(i(t))for(j in t)y(this,j,t[j]);else y(this,t,v(this,e,n,this.getAttribute(t)))}):this.length&&1===this[0].nodeType?!(n=this[0].getAttribute(t))&&t in this[0]?this[0][t]:n:E},removeAttr:function(t){return this.each(function(){1===this.nodeType&&t.split(" ").forEach(function(t){y(this,t)},this)})},prop:function(t,e){return t=K[t]||t,1 in arguments?this.each(function(n){this[t]=v(this,e,n,this[t])}):this[0]&&this[0][t]},data:function(t,e){var n="data-"+t.replace(z,"-$1").toLowerCase(),r=1 in arguments?this.attr(n,e):this.attr(n);return null!==r?x(r):E},val:function(t){return 0 in arguments?this.each(function(e){this.value=v(this,t,e,this.value)}):this[0]&&(this[0].multiple?T(this[0]).find("option").filter(function(){return this.selected}).pluck("value"):this[0].value)},offset:function(t){if(t)return this.each(function(e){var n=T(this),r=v(this,t,e,n.offset()),i=n.offsetParent().offset(),o={top:r.top-i.top,left:r.left-i.left};"static"==n.css("position")&&(o.position="relative"),n.css(o)});if(!this.length)return null;if(!T.contains(D.documentElement,this[0]))return{top:0,left:0};var e=this[0].getBoundingClientRect();return{left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)}},css:function(e,n){if(arguments.length<2){var r,i=this[0];if(!i)return;if(r=getComputedStyle(i,""),"string"==typeof e)return i.style[S(e)]||r.getPropertyValue(e);if(Q(e)){var o={};return T.each(e,function(t,e){o[e]=i.style[S(e)]||r.getPropertyValue(e)}),o}}var s="";if("string"==t(e))n||0===n?s=c(e)+":"+f(e,n):this.each(function(){this.style.removeProperty(c(e))});else for(j in e)e[j]||0===e[j]?s+=c(j)+":"+f(j,e[j])+";":this.each(function(){this.style.removeProperty(c(j))});return this.each(function(){this.style.cssText+=";"+s})},index:function(t){return t?this.indexOf(T(t)[0]):this.parent().children().indexOf(this[0])},hasClass:function(t){return t?O.some.call(this,function(t){return this.test(b(t))},l(t)):!1},addClass:function(t){return t?this.each(function(e){if("className"in this){C=[];var n=b(this),r=v(this,t,e,n);r.split(/\s+/g).forEach(function(t){T(this).hasClass(t)||C.push(t)},this),C.length&&b(this,n+(n?" ":"")+C.join(" "))}}):this},removeClass:function(t){return this.each(function(e){if("className"in this){if(t===E)return b(this,"");C=b(this),v(this,t,e,C).split(/\s+/g).forEach(function(t){C=C.replace(l(t)," ")}),b(this,C.trim())}})},toggleClass:function(t,e){return t?this.each(function(n){var r=T(this),i=v(this,t,n,b(this));i.split(/\s+/g).forEach(function(t){(e===E?!r.hasClass(t):e)?r.addClass(t):r.removeClass(t)})}):this},scrollTop:function(t){if(this.length){var e="scrollTop"in this[0];return t===E?e?this[0].scrollTop:this[0].pageYOffset:this.each(e?function(){this.scrollTop=t}:function(){this.scrollTo(this.scrollX,t)})}},scrollLeft:function(t){if(this.length){var e="scrollLeft"in this[0];return t===E?e?this[0].scrollLeft:this[0].pageXOffset:this.each(e?function(){this.scrollLeft=t}:function(){this.scrollTo(t,this.scrollY)})}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),n=this.offset(),r=q.test(e[0].nodeName)?{top:0,left:0}:e.offset();return n.top-=parseFloat(T(t).css("margin-top"))||0,n.left-=parseFloat(T(t).css("margin-left"))||0,r.top+=parseFloat(T(e[0]).css("border-top-width"))||0,r.left+=parseFloat(T(e[0]).css("border-left-width"))||0,{top:n.top-r.top,left:n.left-r.left}}},offsetParent:function(){return this.map(function(){for(var t=this.offsetParent||D.body;t&&!q.test(t.nodeName)&&"static"==T(t).css("position");)t=t.offsetParent;return t})}},T.fn.detach=T.fn.remove,["width","height"].forEach(function(t){var e=t.replace(/./,function(t){return t[0].toUpperCase()});T.fn[t]=function(i){var o,s=this[0];return i===E?n(s)?s["inner"+e]:r(s)?s.documentElement["scroll"+e]:(o=this.offset())&&o[t]:this.each(function(e){s=T(this),s.css(t,v(this,i,e,s[t]()))})}}),H.forEach(function(e,n){var r=n%2;T.fn[e]=function(){var e,i,o=T.map(arguments,function(n){return e=t(n),"object"==e||"array"==e||null==n?n:Y.fragment(n)}),s=this.length>1;return o.length<1?this:this.each(function(t,e){i=r?e:e.parentNode,e=0==n?e.nextSibling:1==n?e.firstChild:2==n?e:null;var a=T.contains(D.documentElement,i);o.forEach(function(t){if(s)t=t.cloneNode(!0);else if(!i)return T(t).remove();i.insertBefore(t,e),a&&w(t,function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML)})})})},T.fn[r?e+"To":"insert"+(n?"Before":"After")]=function(t){return T(t)[e](this),this}}),Y.Z.prototype=d.prototype=T.fn,Y.uniq=N,Y.deserializeValue=x,T.zepto=Y,T}();window.Zepto=Zepto,void 0===window.$&&(window.$=Zepto),function(t){function e(e,n,r){var i=t.Event(n);return t(e).trigger(i,r),!i.isDefaultPrevented()}function n(t,n,r,i){return t.global?e(n||y,r,i):void 0}function r(e){e.global&&0===t.active++&&n(e,null,"ajaxStart")}function i(e){e.global&&!--t.active&&n(e,null,"ajaxStop")}function o(t,e){var r=e.context;return e.beforeSend.call(r,t,e)===!1||n(e,r,"ajaxBeforeSend",[t,e])===!1?!1:void n(e,r,"ajaxSend",[t,e])}function s(t,e,r,i){var o=r.context,s="success";r.success.call(o,t,s,e),i&&i.resolveWith(o,[t,s,e]),n(r,o,"ajaxSuccess",[e,r,t]),u(s,e,r)}function a(t,e,r,i,o){var s=i.context;i.error.call(s,r,e,t),o&&o.rejectWith(s,[r,e,t]),n(i,s,"ajaxError",[r,i,t||e]),u(e,r,i)}function u(t,e,r){var o=r.context;r.complete.call(o,e,t),n(r,o,"ajaxComplete",[e,r]),i(r)}function c(){}function l(t){return t&&(t=t.split(";",2)[0]),t&&(t==j?"html":t==E?"json":x.test(t)?"script":w.test(t)&&"xml")||"text"}function f(t,e){return""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?")}function h(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=f(e.url,e.data),e.data=void 0)}function p(e,n,r,i){return t.isFunction(n)&&(i=r,r=n,n=void 0),t.isFunction(r)||(i=r,r=void 0),{url:e,data:n,success:r,dataType:i}}function d(e,n,r,i){var o,s=t.isArray(n),a=t.isPlainObject(n);t.each(n,function(n,u){o=t.type(u),i&&(n=r?i:i+"["+(a||"object"==o||"array"==o?n:"")+"]"),!i&&s?e.add(u.name,u.value):"array"==o||!r&&"object"==o?d(e,u,r,n):e.add(n,u)})}var m,g,v=0,y=window.document,b=/