热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

vue+webpack搭建单文件应用和多文件应用webpack.config.js的写法区别

1.前言这几天,都遇到过有人问过相似的问题,就是用vue和webpack搭建目录的时候,怎么把单页面应用的配置改成多文件应用,

1.前言

这几天,都遇到过有人问过相似的问题,就是用vue和webpack搭建目录的时候,怎么把单页面应用的配置改成多文件应用,或者是怎么把多文件应用的配置改成单文件应用。这个情况,我之前有处理过,公司的同事教过我,我就针对这个情况写下此篇文章。各位如果觉得我哪里写得不够好,写错了,欢迎指出,大家一起进步。

2.说明

  1. 首先,我用的vue和webpack的版本都是2.x的,请大家留意自己使用的版本,特别是webpack的版本,1和2还是有些区别的。

  2. 然后,项目搭建的流程我不多说了,之前写过文章,网上也有很多好文章值得学习。接下来我只针对webpack.config.js这个配置文件说明,因为我做项目的时候,改动的基本就是这里,项目的文件虽然也有写法上的改动,但是那个改动相信不会难到大家,如果真的不知如何下手,我往后可能会再写文章。

3.单文件应用的配置

由于现在单文件应用写得比较多,一开始我就先放单文件应用的配置文件吧,代码如下

let path = require('path');
let webpack = require('webpack');
/*html-webpack-plugin插件,webpack中生成HTML的插件,具体可以去这里查看https://www.npmjs.com/package/html-webpack-plugin*/
let HtmlWebpackPlugin = require('html-webpack-plugin');
/*一个根据模式匹配获取文件列表的node模块。有关glob的详细用法可以在这里看到——https://github.com/isaacs/node-glob*/
let glob = require('glob');
/*webpack插件*/
let CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
let UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
let publicPath = '/dist/';
//IP地址
let serverHost = getIPAdress();
let config = {//入口文件entry: {index: path.resolve(__dirname, 'src/js/page/index.js'),vendors: ['vue', 'vue-router','vue-resource','vuex','element-ui','element-ui/lib/theme-default/index.css'] // 需要进行单独打包的文件},//出口文件output: {path: path.join(__dirname, 'dist'), //输出目录的配置,模板、样式、脚本、图片等资源的路径配置都相对于它publicPath: publicPath, //模板、样式、脚本、图片等资源对应的server上的路径filename: 'js/[name].js', //每个页面对应的主js的生成配置// chunkFilename: 'js/[name].asyncChunk.js?[chunkhash]' //chunk生成的配置chunkFilename: 'js/[name].asyncChunk.js?'+new Date().getTime() //chunk生成的配置},module: {//加载器rules: [{test: /\.vue$/,loader: 'vue-loader',options: {loaders: {scss: 'vue-style-loader!css-loader!sass-loader', // sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // }}},{test: /\.html$/,loader: "raw-loader"},{test: /\.css$/,loader: 'style-loader!css-loader'},{test: /\.js$/,exclude: /node_modules/,loader: "babel-loader",options: {presets: ["es2015","stage-0"],plugins: ['syntax-dynamic-import']}},{test: /\.scss$/,loader: 'style-loader!css-loader!sass-loader'},{test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,loader: 'file-loader'},{//图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求//如下配置,将小于8192byte的图片转成base64码test: /\.(png|jpg|gif)$/,loader: 'url-loader?limit=8192&name=images/[hash].[ext]'}]},//插件plugins: [//生成HTML文件new HtmlWebpackPlugin({filename: path.resolve(__dirname, 'dist/html/index.html'), //生成的html存放路径,相对于pathtemplate: path.resolve(__dirname, 'src/html/index.html'), //ejs模板路径,前面最好加上loader用于处理inject: 'body', //js插入的位置,true/'head'/'body'/falsechunks: ['load', 'vendors', 'vendor1', 'vendor2', 'index'],hash: true}),//提取公共模块new CommonsChunkPlugin({name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk//name: ['vendors', 'vendor1', 'vendor2', 'load'], // 将公共模块提取,生成名为`vendors`的chunkminChunks: 2, //公共模块被使用的最小次数。配置为2,也就是同一个模块只有被2个以外的页面同时引用时才会被提取出来作为common chunks// children:true //如果为true,那么公共组件的所有子依赖都将被选择进来}),//在async chunk 里面找到复用 >= 2次的模块再单独提取出来new CommonsChunkPlugin({async: 'lazy',minChunks: (module, count) => ( //count 模块被复用的次数count >= 2)}),new UglifyJsPlugin({ //压缩代码compress: {warnings: false,drop_debugger: true,drop_console: true},except: ['$super', '$', 'exports', 'require', 'define', 'module'] //排除关键字})],//使用webpack-dev-serverdevServer: {contentBase: path.join(__dirname, "/"),host: serverHost,port: 9090, //默认9090inline: true, //可以监控js变化hot: true//热启动},resolve: {alias: {vue: 'vue/dist/vue.js'},extensions:['.js','.scss','.vue','.json']// 可以不加后缀, 直接使用 import xx from 'xx' 的语法}
};
module.exports = config;
/*** @description 获取本地IP地址* @returns {string|*}*/
function getIPAdress() {let interfaces = require('os').networkInterfaces();for (let devName in interfaces) {let iface = interfaces[devName];for (let i = 0; i }

4.多文件应用的配置

多文件现在用的不算很多,主要有时候会负责公司一些活动的小项目会用到,代码如下。

let path = require('path');
let webpack = require('webpack');
/*html-webpack-plugin插件,webpack中生成HTML的插件,具体可以去这里查看https://www.npmjs.com/package/html-webpack-plugin*/
let HtmlWebpackPlugin = require('html-webpack-plugin');
/*一个根据模式匹配获取文件列表的node模块。有关glob的详细用法可以在这里看到——https://github.com/isaacs/node-glob*/
let glob = require('glob');
/*webpack插件*/
let CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
let UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
let publicPath = '/dist/';
//通过getEntry函数获取所有js脚本
let jsEntries = getEntry('./src/js/page/*.js');
//IP地址
let IPAddress = getIPAdress();
let serverHost = IPAddress;
let config = {//入口文件entry: jsEntries,// entry: {// index:jsEntries,// vendors: ['vue', 'vue-router','vue-resource'] // 需要进行单独打包的文件// },//出口文件output: {path: path.join(__dirname, 'dist'), //输出目录的配置,模板、样式、脚本、图片等资源的路径配置都相对于它publicPath: publicPath, //模板、样式、脚本、图片等资源对应的server上的路径filename: 'js/[name].js', //每个页面对应的主js的生成配置chunkFilename: 'js/[id].chunk.js?[chunkhash]' //chunk生成的配置},module: {rules: [{test: /\.vue$/,loader: 'vue-loader',options: {loaders: {scss: 'vue-style-loader!css-loader!sass-loader', // sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // }}},{test: /\.html$/,loader: "raw-loader"},{test: /\.css$/,loader: 'style-loader!css-loader'},{test: /\.js$/,exclude: /node_modules/,loader: "babel-loader",options: {presets: ["es2015","stage-0"],plugins: ['syntax-dynamic-import']}},{test: /\.scss$/,loader: 'style-loader!css-loader!sass-loader'},{test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,loader: 'file-loader'},{//图片加载器,雷同file-loader,更适合图片,可以将较小的图片转成base64,减少http请求//如下配置,将小于8192byte的图片转成base64码test: /\.(png|jpg|gif)$/,loader: 'url-loader?limit=8192&name=images/[hash].[ext]'}]},plugins: [new CommonsChunkPlugin({name: 'vendors', // 将公共模块提取,生成名为`vendors`的chunk//name: ['vendors', 'vendor1', 'vendor2', 'load'], // 将公共模块提取,生成名为`vendors`的chunkminChunks: 2, //公共模块被使用的最小次数。配置为2,也就是同一个模块只有被2个以外的页面同时引用时才会被提取出来作为common chunks// children:true //如果为true,那么公共组件的所有子依赖都将被选择进来})new UglifyJsPlugin({ //压缩代码compress: {warnings: false,drop_debugger: true,drop_console: true},except: ['$super', '$', 'exports', 'require', 'define', 'module'] //排除关键字})],//使用webpack-dev-serverdevServer: {contentBase: path.join(__dirname, "/"),host: serverHost,port: 9090, //默认9090inline: true, //可以监控js变化hot: true//热启动},resolve: {alias: {vue: 'vue/dist/vue.js'},extensions:['.js','.scss','.vue','.json']// 可以不加后缀, 直接使用 import xx from 'xx' 的语法}
};
//获取目录下的所有.html文件的名称
let tplPages = Object.keys(getEntry('./src/html/*.html'));
tplPages.forEach((pathname)=> {let conf = {filename: path.resolve(__dirname, 'dist/html/'+ pathname +'.html'), //生成的html存放路径,相对于pathtemplate: path.resolve(__dirname, 'src/html/'+ pathname +'.html'), //ejs模板路径,前面最好加上loader用于处理inject: 'body', //js插入的位置,true/'head'/'body'/falsechunks: ['load', 'vendors', 'vendor1', 'vendor2', 'index'],hash: true};
//如果文件名和入口文件名所对应的js有匹配(如:index.html和index.js就是相匹配的,就往index.html里面插入index.js;share.html和share.js就是相匹配的,就往share.html里面插入share.js)if (pathname in config.entry) {conf.inject = 'body';conf.chunks = ['vendors', pathname];conf.hash = true;}
//生成配置压栈config.plugins.push(new HtmlWebpackPlugin(conf));
});
module.exports = config;/*** @description 获取本地IP地址* @returns {string|*}*/
function getIPAdress() {let interfaces = require('os').networkInterfaces();for (let devName in interfaces) {let iface = interfaces[devName];for (let i = 0; i }
function getEntry(globPath) {//获取globPath路径下的所有文件let files = glob.sync(globPath);let entries = {},entry, dirname, basename, pathname, extname;//循环for (let i = 0; i quux*/basename = path.basename(entry, extname);pathname = path.join(dirname, basename);//路径合并entries[basename] = entry;}//返回map=>{fileName:fileUrl}return entries;
}

5.区别总结

一对比,区别就是出来了,但是写法是大同小异的。有区别是主要是下面几点

1.入口文件的区别,单页面应用入口文件是就是一个index.js('src/js/page/index.js')。而多页面应用的入口文件是所有需要用到的页面let jsEntries = getEntry('./src/js/page/*.js');。(getEntry方法是返回一个目录下所有的.js文件的名称和路径,jsEntries就是一个对象数组,里面包含着./src/js/page目录下所有的.js文件的名称和路径)

2.在多文件应用的配置中,HtmlWebpackPlugin这个插件是提取出来,在遍历getEntry('./src/html/*.html')的过程中,执行一次就往配置(config.plugins)那里push一次(config.plugins.push(new HtmlWebpackPlugin(conf)))。为什么这样写,大家应该很清楚了,有多少个入口文件,就得写多少次这个插件,new HtmlWebpackPlugin多少次,如果入口文件只有一两个,两三个还好,如果有100个入口文件,岂不是要在config.plugins那里写100次new HtmlWebpackPlugin,所以就标题文字遍历了,方便点。

结语

好了。单文件应用和多文件应用上,webpack.config.js是大同小异的,区别就讨论到这里了。如果文章觉得那里写得不好或者写错了,欢迎指出。同时也希望,这篇文章能帮到大家!



推荐阅读
  • 为什么多数程序员难以成为架构师?
    探讨80%的程序员为何难以晋升为架构师,涉及技术深度、经验积累和综合能力等方面。本文将详细解析Tomcat的配置和服务组件,帮助读者理解其内部机制。 ... [详细]
  • Vue应用预渲染技术详解与实践 ... [详细]
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • LDAP服务器配置与管理
    本文介绍如何通过安装和配置SSSD服务来统一管理用户账户信息,并实现其他系统的登录调用。通过图形化交互界面配置LDAP服务器,确保用户账户信息的集中管理和安全访问。 ... [详细]
  • Webpack 初探:Import 和 Require 的使用
    本文介绍了 Webpack 中 Import 和 Require 的基本概念和使用方法,帮助读者更好地理解和应用模块化开发。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 大家好,我是李白。本文将分享一个从零开始的全栈项目,涵盖了设计、前端、后端和服务端的全面学习过程。通过这个项目,我希望能够帮助初学者更好地理解和掌握全栈开发的技术栈。 ... [详细]
  • Vue CLI 初始化 Webpack 项目时,main.js 文件是如何被调用的? ... [详细]
  • 在最近的学习过程中,我对Vue.js中的Prop属性有了更深入的理解,并认为这一知识点至关重要,因此在此记录一些心得体会。Prop属性用于在组件之间传递数据。由于每个组件实例的作用域都是独立的,无法直接引用父组件的数据。通过使用Prop,可以将数据从父组件安全地传递到子组件,确保数据的隔离性和可维护性。 ... [详细]
  • 作为软件工程专业的学生,我深知课堂上教师讲解速度之快,很多时候需要课后自行消化和巩固。因此,撰写这篇Java Web开发入门教程,旨在帮助初学者更好地理解和掌握基础知识。通过详细记录学习过程,希望能为更多像我一样在基础方面还有待提升的学员提供有益的参考。 ... [详细]
  • 本文探讨了如何通过检测浏览器类型来动态加载特定的npm包,从而优化前端性能。具体而言,仅在用户使用Edge浏览器时加载相关包,以提升页面加载速度和整体用户体验。此外,文章还介绍了实现这一目标的技术细节和最佳实践,包括使用User-Agent字符串进行浏览器识别、条件加载策略以及性能监控方法。 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
  • 本文详细介绍了在 Vue.js 前端框架中集成 vue-i18n 插件以实现多语言支持的方法。通过具体的配置步骤和示例代码,帮助开发者快速掌握如何在项目中实现国际化功能,提升用户体验。同时,文章还探讨了常见的多语言切换问题及解决方案,为开发人员提供了实用的参考。 ... [详细]
  • 一、Tomcat安装后本身提供了一个server,端口配置默认是8080,对应目录为:..\Tomcat8.0\webapps二、Tomcat8.0配置多个端口,其实也就是给T ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
author-avatar
MM我男神
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有