按如下步骤可正常配置多页面架构javascript
记得安装 node-glob 安装命令:npm install node-glob --save-devphp
文件附加css
webpack.base.conf.js --参考more start 处html
var path = require('path') var utils = require('./utils') var config = require('../config') var vueLoaderConfig = require('./vue-loader.conf') var webpack=require('webpack'); //加入webpack对象 //more var glob = require('glob'); //node-glob var entries = getEntry('./src/views/**/*.js'); // 得到入口js文件. views替换了module //more end function resolve (dir) { return path.join(__dirname, '..', dir) } function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function (entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径 entries[pathname] = entry; }); console.log("base-entrys:",entries); return entries; } module.exports = { entry:entries , // entry: { // app: './src/main.js' // }, output: { path: config.build.assetsRoot, filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), 'basecommon':'./../../../common',//base组件引入公共样式 'components':'./../components',//非base组件,./../common 'api':'./../../api',//非base组件 'base':'./../base' //非base组件引入base组件 } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test')] }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('images/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, plugins: [ new webpack.ProvidePlugin({ $:"jquery", jQuery:"jquery", "windows.jQuery":"jquery" }) ] }
webpack.dev.conf.js --参考more start 处前端
var utils = require('./utils') var webpack = require('webpack') var config = require('../config') var merge = require('webpack-merge') var baseWebpackConfig = require('./webpack.base.conf') var HtmlWebpackPlugin = require('html-webpack-plugin') var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') //more var path = require('path'); var glob = require('glob'); //more end // add hot-reload related code to entry chunks Object.keys(baseWebpackConfig.entry).forEach(function (name) { baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) }) function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function(entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径 entries[pathname] = entry; }); console.log("dev-entrys:",entries); return entries; } //more end module.exports = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) }, // cheap-module-eval-source-map is faster for development devtool: '#cheap-module-eval-source-map', plugins: [ new webpack.DefinePlugin({ 'process.env': config.dev.env }), // https://github.com/glenjamin/webpack-hot-middleware#installation--usage new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), // https://github.com/ampedandwired/html-webpack-plugin // new HtmlWebpackPlugin({ // filename: 'index.html', // template: 'index.html', // inject: true // }), new FriendlyErrorsPlugin() ] }) //more start 先定义后插入 var pages = getEntry('./src/views/**/*.html'); console.log("dev pages----------------------"); for (var pathname in pages) { console.log("filename:" + pathname + '.html'); console.log("template:" + pages[pathname]); // 配置生成的html文件,定义路径等 var conf = { filename: pathname + '.html', template: pages[pathname], // 模板路径 minify: { //传递 html-minifier 选项给 minify 输出 removeComments: true }, inject: 'body', // js插入位置 chunks: [pathname, "vendor", "manifest"] // 每一个html引用的js模块,也能够在这里加上vendor等公用模块 }; // 须要生成几个html文件,就配置几个HtmlWebpackPlugin对象 module.exports.plugins.push(new HtmlWebpackPlugin(conf)); }
webpack.prod.conf.js --参考more start 处vue
var path = require('path') var utils = require('./utils') var webpack = require('webpack') var config = require('../config') var merge = require('webpack-merge') var baseWebpackConfig = require('./webpack.base.conf') var CopyWebpackPlugin = require('copy-webpack-plugin') var HtmlWebpackPlugin = require('html-webpack-plugin') var ExtractTextPlugin = require('extract-text-webpack-plugin') var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') //more var path = require('path'); var glob = require('glob'); //more end var env = config.build.env var webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true }) }, devtool: config.build.productionSourceMap ? '#source-map' : false, output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, sourceMap: true }), // extract css into its own file new ExtractTextPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css') }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. new OptimizeCSSPlugin({ cssProcessorOptions: { safe: true } }), // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin /* new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }),*/ // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function (module, count) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor'] }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { var CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = webpackConfig //more start function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function(entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径 entries[pathname] = entry; }); console.log("pro-entrys:",entries); return entries; } var pages = getEntry('./src/views/**/*.html'); console.log("pro pages----------------------"); for (var pathname in pages) { console.log("filename:" + pathname + '.html'); console.log("template:" + pages[pathname]); // 配置生成的html文件,定义路径等 var conf = { filename: pathname + '.html', template: pages[pathname], // 模板路径 minify: { //传递 html-minifier 选项给 minify 输出 removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, inject: 'body', // js插入位置 chunks: [pathname, "vendor", "manifest"], // 每一个html引用的js模块,也能够在这里加上vendor等公用模块 // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }; // 须要生成几个html文件,就配置几个HtmlWebpackPlugin对象 module.exports.plugins.push(new HtmlWebpackPlugin(conf)); }
-----------------横线内为转的-----------------------java
首先,要大概知道webpack是什么,webpack的插件都是作什么用的,vue是什么,而后看完以后也能够去补充一下这些方面的知识。node
须要安装的有:jquery
npm install -g vue-cli
npm install webpack -g
vue init wepack vue-multipage-demo
如上所示,这条命令的意思是使用vue的init命令,建立一个基于webpack组件化管理的项目。这将会在D:\WS_WebStorm目录下建立新目录vue-multipage-demo。
图2
如图2,在通过设置以后,能够看到已经生成了一个项目vue-multipage-demo,接下来须要切换到项目目录下进行操做。在资源管理器中,咱们能够看到已经生成了这样的目录:
图3
如图3,各个文件夹和文件分别是:
build webpack构建过程的设置文件,包括调试和发布版本以及一些工具函数
config 这里是webpack-dev-server的一些设定,关于webpack和webpack-dev-server的设定,详见官方文档
src 项目的源文件所在,按照你须要的样子写js和html文件,webpack将打包成浏览器可识别的,如ES6
static 这里是存放静态资源的地方,在build以后会生成dist文件夹,这个文件夹中的文件会原封不动放进去
.babelrc webpack插件babel的设置
.editorconfig 这是atom编辑器生成的配置文件,在各个项目中能够自由配置
.eslintignore 使用eslint检测代码是否符合规则的忽略目录,用于eslint设置
.gitignore 使用Git版本管理时须要忽略的目录,用于git设置
index.html 项目生成后的入口页面,由于vue默认是使用单页面的,因此在webpack中同时也只有这一个入口
package.json nodejs的配置
README.md 说明文件,其中说明了使用vue-cli建立项目以后应该怎么作
dist build以后生成的目录,其中存放webpack打包以后的结果,webpack中须要指定build规则
表1
图4
如图4,执行这两条命令,切换到项目目录下,使用npm的安装命令,对已经生成的package.json所依赖的组件进行安装。固然,咱们以后还会安装一些其余的插件。webpack
虽说,在项目开发中,插件的补充是根据需求进行增减的,可是在这个项目中,有一些基本的须要添加的插件,我在这里提出。package.json中的代码以下:
"dependencies": { "babel-runtime": "^6.0.0", "bootstrap": "^3.3.7", "bootstrap-table": "^1.11.0", "font-awesome": "^4.6.3", "jquery": "^3.1.0", "node-glob": "^1.2.0", "vue": "^1.0.21", "vue-resource": "^0.9.3" }, "devDependencies": { "babel-core": "^6.0.0", "babel-eslint": "^6.1.2", "babel-loader": "^6.0.0", "babel-plugin-transform-runtime": "^6.0.0", "babel-preset-es2015": "^6.0.0", "babel-preset-stage-2": "^6.0.0", "babel-register": "^6.0.0", "bootstrap-loader": "^2.0.0-beta.9", "connect-history-api-fallback": "^1.1.0", "css-loader": "^0.23.0", "dynamics.js": "^1.1.5", "eslint": "^2.10.2", "eslint-config-standard": "^5.1.0", "eslint-friendly-formatter": "^2.0.5", "eslint-loader": "^1.3.0", "eslint-plugin-html": "^1.3.0", "eslint-plugin-promise": "^1.0.8", "eslint-plugin-standard": "^1.3.2", "eventsource-polyfill": "^0.9.6", "express": "^4.13.3", "extract-text-webpack-plugin": "^1.0.1", "file-loader": "^0.8.4", "function-bind": "^1.0.2", "html-webpack-plugin": "^2.8.1", "http-proxy-middleware": "^0.12.0", "json-loader": "^0.5.4", "ora": "^0.2.0", "shelljs": "^0.6.0", "url-loader": "^0.5.7", "vue-hot-reload-api": "^1.2.0", "vue-html-loader": "^1.0.0", "vue-loader": "^8.3.0", "vue-style-loader": "^1.0.0", "webpack": "^1.13.2", "webpack-dev-middleware": "^1.4.0", "webpack-hot-middleware": "^2.6.0", "webpack-merge": "^0.8.3" }
其中包括了由项目自动生成的一些插件。
我梳理一下,主要有下面这些,其中标注红色的是我本身用来开发依赖的:
dependencies:
babel-runtime
bootstrap
bootstrap-table
font-awesome
jQuery
node-glob
vue
devDependencies:
bootstrap-loader
dynamics.js
那么主要就是添加一下node-glob和vue,其余的若是须要再进行添加。nodej-glob是用来获取路径的,vue是须要依赖的主要部分。
这一步最重要。
在咱们没有动过以前,src目录是这个样子的,如图5:
图5
首先,建立以下目录结构:
src
|
—–module
|
—–index
|
—–index.html
—–main.js
将以前外面的index.html放进来,main.js放入index,更名为index.js,此处必定注意名称要相同,不然后面寻找路径时是找不到对应文件的。而后将App.vue放入components。最后是这样的,如图6:
图6
这时候须要对文件进行必定的修改。首先是index.js,对App的调用,路径修改,如图7
图7
修改完了上面的资源,咱们要修改webpack的配置。
咱们介绍一下webpack在这个项目中本来的顺序:因为webpack将全部的js,css/less,html等都视为js的可引入资源,因此入口就成了js文件。那么webpack须要设置一个入口的js文件,这个入口的js文件就是main.js,在webpack中有一个插件,叫作html-webpack-plugin,这个是用来将js和html对应起来,也就是若干js对应一个html,在原来的项目中html就是index.html。
在运行npm run dev 或者build以后,就会将文件打包,因为dev的时候文件是在内存中,因此build能够看得比较清楚,在dist目录中,会有一个index.html,其中已经打包进了
添加下面两行在这里,图8中位置,
var glob = require('glob'); var entries = getEntry('./src/module/**/*.js'); // 得到入口js文件
图8
这里的glob,就是前面提到的node-glob。将entry修改成这个,图9中位置,
图9
而后在下面添加getEntry方法。
function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function (entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径 entries[pathname] = entry; }); console.log("base-entrys:"); console.log(entries); return entries; }
由于咱们的想法是要将全部的业务模块放在module中,这样一来的话,就在module中细分,最后输出html都在dist的module下。这里的字符串操做也是和路径的状况相匹配的,若是有须要进行其余方式的设定,注意在这里修改路径的识别。
在打开后,咱们会发如今这里有一个插件的设置,如图10:
图10
这个 插件就是刚才提到的将输出html页面build结果的地方。
首先,添加
var path = require('path'); var glob = require('glob');
用来引入path和glob工具。
将图10中的那一段去掉,由于咱们要本身来添加这个插件。
一样的,在这个文件中也须要添加这个函数,放在文件的下面,
function getEntry(globPath) { var entries = {}, basename, tmp, pathname; glob.sync(globPath).forEach(function(entry) { basename = path.basename(entry, path.extname(entry)); tmp = entry.split('/').splice(-3); pathname = tmp.splice(0, 1) + '/' + basename; // 正确输出js和html的路径 entries[pathname] = entry; }); console.log("dev-entrys:"); console.log(entries); return entries; }
而后再添加这一段,
var pages = getEntry('./src/module/**/*.html'); console.log("dev pages----------------------"); for (var pathname in pages) { console.log("filename:" + pathname + '.html'); console.log("template:" + pages[pathname]); // 配置生成的html文件,定义路径等 var conf = { filename: pathname + '.html', template: pages[pathname], // 模板路径 minify: { //传递 html-minifier 选项给 minify 输出 removeComments: true }, inject: 'body', // js插入位置 chunks: [pathname, "vendor", "manifest"] // 每一个html引用的js模块,也能够在这里加上vendor等公用模块 }; // 须要生成几个html文件,就配置几个HtmlWebpackPlugin对象 module.exports.plugins.push(new HtmlWebpackPlugin(conf)); }
这个一样是经过指定的路径,按照我以前的预想,进行html的迭代获取,而后对每个html进行设定。咱们的多页面输出关键也就在这个地方。
html-webpack-plugin这个插件能够为一个html输出打包对应的js模块。chunks就是对应的js模块,也就是webpack的入口,包括entries和使用了webpack.optimize.CommonsChunkPlugin插件声称的公共js模块。这些模块都有各自的名字,entries的名字就是前面经过getEntry函数生成的一组入口组件名称和路径。
经过上面的修改,就作成了这样一件事情:为webpack提供多个js入口,而这些js入口和html页面是在同一个文件夹下的,那么它们的key或者说name就是相同的。这样在循环的时候,就会获取到对应的js和html,经过循环建立多个html-webpack-plugin来将不一样的js模块打包进对应的html,并经过webpack批量构建,在dist中就会产生咱们须要的一组html文件。而这些html文件都是已经通过压缩的,js代码也通过了压缩处理。
和webpack.dev.conf.js中作相似的处理,先注释掉原来的HtmlWebpackPlugin,而后在下面添加函数,经过迭代插入多个HtmlWebpackPlugin。
HtmlWebpackPlugin更多的设置,到webpack的官网上查看。
而后使用npm run dev或者npm run build来构建。在构建的过程当中,可能会出现一些依赖插件不存在的错误,须要先使用npm install –save-dev 插件名 来安装相应的依赖插件。
这样,index.html就被构建到了dist/module/index.html中。
但功能是如出一辙的。
vue的使用在这里不赘述。这里说明一下,咱们的module中,是系统的业务模块,components中是功能模块和细分的代码模块,也就是vue组件。因为webpack这里带了babel,因此在js源文件中可使用ES6的写法。在业务js中,就能够经过导入,组合,自定义vue组件,来实现相应的业务需求。
好比在我如今拆分的这个网页中,包括这么几个部分:
这是对一个bootstrap网站模板index页面进行拆分后的结果,css,html都放在对应的vue中,固然,我也引入了jquery。
vue的组件能够实现继承和mixin。可以很好的进行组件化开发,而经过webpack将src的源代码进行构建变成浏览器可以识别的正常文件。这样就大大下降了前端开发的重复性。
/2016-09-13 补 /
这个是个人一个demo,提供给学生用的。
http://www.huyangsheng.cn/resource/vue-multipage-demo.rar
以上文章是参考了几篇以后弄出来一个适合本身用的。
参考:
https://github.com/Coffcer/Blog/issues/1
http://cnu4.github.io/2016/03/21/Webpack-Vue-MultiplePage/
http://jiongks.name/blog/just-vue/?from=groupmessage&isappinstalled=1
http://www.cnblogs.com/grimm/p/5768433.html
https://github.com/yaoyao1987/vue-cli-multipage
---------------------转发结束--------------------