使用webpack搭建一个多页应用
一、前言
最近需要为公司的活动写8个左右的移动端分享页面,有比较多的页面是公用的,如果用传统的方式来写的话,对于公用的代码抽取,css代码的压缩都是比较麻烦的,所以选择了webpack来搭建一个基本的多页面应用。大概有一下的功能点:
1.自动添加浏览器前缀到CSS文件中
2.自动压缩合并 CSS 和 JS 文件
3.自动清理打包后的dist文件夹
4.自动生成HTML文件
5.自动抽取CSS文件
6.本地开发热更新
7.HTML模板的导入等
二、目录结构
三、安装依赖
autoprefixer:自动为CSS文件添加浏览器前缀
clean-webpack-plugin:自动清除打包之后的文件
extract-text-webpack-plugin:CSS文件的单独抽取
html-loader:导入公用的HTML模板,如下使用
webpack:主要的打包工具
webpack-dev-server:本地开发的热更新服务器
webpack-merge:对webpack配置进行合并操作
hogan:前端的HTML模板
http-server:http服务器,可以用于访问打包之后的静态资源
四、具体的package.json文件
{
"name": "activityShare",
"version": "1.0.0",
"description": "活动分享",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server --inline --progress --config config/webpack.config.dev.js",
"build": "webpack -p --config config/webpack.config.prod.js",
"serve": "http-server dist -p 9999"
},
"keywords": [
"jqery、css、html"
],
"author": "lidongheng",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^7.1.3",
"clean-webpack-plugin": "^0.1.16",
"css-loader": "^0.28.7",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^2.30.1",
"http-server": "^0.10.0",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.6",
"postcss-url": "^7.2.1",
"style-loader": "^0.18.2",
"url-loader": "^0.5.8",
"webpack": "^3.5.5",
"webpack-dev-server": "^2.7.1",
"webpack-merge": "^4.1.0"
},
"dependencies": {
"hogan": "^1.0.2"
}
}
五、config.js文件包含一些可配置的选项
module.exports = {
dev: {
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://192.168.9.19:8080',
changeOrigin: true, //改变源
pathRewrite: {
'^/api': ''
}
}
},
host: '0.0.0.0', // 写成0.0.0.0手机可以通过局域网访问,localhost无法使用手机访问的
port: 8888,
autoOpenBrowser: false, // 是否自动打开浏览器
errorOverlay: true, // 编译错误的时候,在浏览器显示mask
poll: false,
},
prod: {
assetsPublicPath: '/'
}
}
六、dev.env.js文件和prod.env.js文件,用于定义开发环境和生产环境
七、webpack基本配置文件webpack.config.base.js
const path = require("path");
// 引入插件,自动生成HTML文件的插件
const HTMLWebpackPlugin = require("html-webpack-plugin");
// 清理 dist 文件夹
const CleanWebpackPlugin = require("clean-webpack-plugin")
// 抽取 css 到单独的文件
const ExtractTextPlugin = require("extract-text-webpack-plugin");
// 引入webpack
const Webpack = require("webpack");
// 基本配置
const config = require("./config"); // 解析路径,当前base文件的上一级路径
function resolve (dir) {
return path.join(__dirname, '..', dir)
} // 计算HtmlWebpackPlugin的参数
// template是html文件的名称,title是html文件中的title值
function getHtmlWebpackPluginParams(template,title){
// 生成的HTML文件放到/dist/view目录下
return {
filename: `view/${template}.html`, // 生成的文件放在/dist/view目录下
template: resolve(`src/view/${template}.html`), // 模板的位置
title: title, // 设置HTML文件中的title值
inject: true, // 插入的script标签放在body后面
hash: true, // 产生hash值
chunks: [template, 'common'], // script标签中插入的文件为对应html文件的js以及公用的common
}
} var configs = {
// 多页应用,所以在入口处设置多个入口的JS文件
entry: {
"common": ["./src/page/common/index.js"], // 公用的JS文件
"activitydetail": ["./src/page/activitydetail/index.js"], // 活动详情页面
"specialdetail": ["./src/page/specialdetail/index.js"], // 活动详情页面
"signup": ["./src/page/signup/index.js"], // 活动详情报名页面
"specialsignup": ["./src/page/specialsignup/index.js"], // 专题详情报名页面
"selectteam": ["./src/page/selectteam/index.js"], // 选择团队的页面
"createteam": ["./src/page/createteam/index.js"], // 创建团队的页面
"viewmember": ["./src/page/viewmember/index.js"], // 查看成员的页面
"download": ["./src/page/download/index.js"], // 下载页面的
},
output:{
filename: 'js/[name].[chunkhash].js', // 【chunkhash】改变内容的时候,hash值就会改变,到时候会强制浏览器获取新的文件
publicPath: process.env.NODE_ENV === 'prod'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath,
path: resolve('dist') // 打包的文件放到/dist下
},
externals : {
'jquery' : 'window.jQuery' // 在页面中通过script引入JQ,在page目录下对应的JS文件可以直接使用$符号
},
// 加载器
module: {
rules: [
{
// 对 css 后缀名进行处理
test:/\.css$/,
// 抽取 css 文件到单独的文件夹
use: ExtractTextPlugin.extract({
fallback: "style-loader", // 编译后用什么style-loader来提取css文件
use: [
{
loader:"css-loader",
options:{
minimize:true, // 开启 css 压缩
}
},
{
loader:"postcss-loader",
}
]
})
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 100,
name: path.posix.join('resource/img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 100,
name: path.posix.join('resource/media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 100,
name: path.posix.join('resource/fonts/[name].[hash:7].[ext]')
}
},
{
test: /\.string$/,
loader: 'html-loader'
}
],
},
// 别名
resolve : {
alias : {
'@' : resolve('src'),
node_modules : resolve('node_modules'),
utils : resolve('src/utils'),
page : resolve('src/page'),
service : resolve('src/service'),
image : resolve('src/image')
}
},
plugins:[
// 抽取公用的JS文件,打包到/dist/js/common.js文件中,也会把common 的chunk打包到/dist/js/common.js中
new Webpack.optimize.CommonsChunkPlugin({
name: "common", // 入口中的common chunk
filename: "js/common.[hash].js"
}),
// 自动清理 dist 文件夹
new CleanWebpackPlugin(["dist"],{
root: resolve('/'),
verbose: true,
dry: false
}),
// 将 css 抽取到/dist/css/xxx.css
new ExtractTextPlugin("css/[name].css"),
// 自动生成 HTML 插件
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('activitydetail','活动详情')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('specialdetail','专题详情')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('signup','填写报名单')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('specialsignup','填写报名单')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('selectteam','选择团队')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('createteam','创建团队')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('viewmember','查看成员')),
new HTMLWebpackPlugin(getHtmlWebpackPluginParams('download','下载青未了'))
]
} module.exports = configs;
八、本地开发的基本配置文件webpack.config.dev.js
const path = require("path");
// 引入基础配置文件
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入webpack
const Webpack = require("webpack");
// 配置
const config = require("./config"); // 合并配置文件
module.exports = webpackMerge(webpackBase,{
// 配置 webpack-dev-server
devServer:{
// 项目根目录
contentBase: path.join(__dirname, '..', 'dist'),
clientLogLevel: 'warning',
hot: true, // 启用 webpack 的模块热替换特性,此特性需要加载plugins:webpack.HotModuleReplacementPlugin
compress: true, // 开启gzip压缩
host: config.dev.host,
progress: true,
port: config.dev.port,
open: config.dev.autoOpenBrowser, // 不自动打开浏览器
publicPath: config.dev.assetsPublicPath,
// 错误、警告展示设置
overlay: config.dev.errorOverlay ?
{ errors: true, warnings: false } : false,
watchOptions: {
poll: config.dev.poll
},
// 代理
proxy: config.dev.proxyTable
},
plugins: [
// DefinePlugin 允许创建一个在编译时可以配置的全局常量,可以在JS文件中根据这些定义的变量来定义不同的行为
new Webpack.DefinePlugin({
'process.env': require("./dev.env")
}),
// 热加载需要配置的插件
new Webpack.HotModuleReplacementPlugin()
]
})
九、生产环境打包的webpack.config.prod.js
// 引入基础配置
const webpackBase = require("./webpack.config.base");
// 引入 webpack-merge 插件
const webpackMerge = require("webpack-merge");
// 引入 webpack
const webpack = require("webpack"); // 合并配置文件
module.exports = webpackMerge(webpackBase,{
plugins:[
// DefinePlugin 允许创建一个在编译时可以配置的全局常量,可以在JS文件中根据这些定义的变量来定义不同的行为
new webpack.DefinePlugin({
'process.env': require("./prod.env")
}),
// 代码压缩
new webpack.optimize.UglifyJsPlugin({
// 开启 sourceMap
sourceMap: true
})
]
});
十、主要参考了vue-cli的配置文件结构,有webpack基础的同学应该都能看懂,把主要的配置文件贴出来,有不懂的请留言。还有一点就是没有配置ES6语法的转换,而是直接使用了webpack对js文件的打包,有需要的可以参考vue-cli进行配置。demo
使用webpack搭建一个多页应用的更多相关文章
- vue入门(三)----使用vue-cli搭建一个单页富应用
上面两节我们说了vue的一些概念,其实说的知识一点基础,这部分知识我觉得更希望大家到官网进行学习,因为在这里说的太多我觉得也只是对官网的照搬照抄而已.今天我们来学习一下vue-cli的一些基础知识,并 ...
- 一步步从零开始用 webpack 搭建一个大型项目
开篇 很多人都或多或少使用过 webpack,但是很少有人能够系统的学习 webpack 配置,遇到错误的时候就会一脸懵,不知道从哪查起?性能优化时也不知道能做什么,网上的优化教程是不是符合自己的项目 ...
- 从零开始搭建一个react项目
Nav logo 120 发现 关注 消息 4 搜索 从零开始搭建一个react项目 96 瘦人假噜噜 2017.04.23 23:29* 字数 6330 阅读 32892评论 31喜欢 36 项目地 ...
- 26、前端知识点--利用webpack搭建脚手架一套完整流程
前言 我们的目标是利用webpack搭建一个基于react + react-router +dva + es6 + less + antd用于中后台开发的脚手架,同学们可能会说社区里那么多优秀的脚手架 ...
- 搭建一个属于自己的webpack config(-)
搭建一个属于自己的webpack config(-) 前期准备 环境说明 mac 10.12.6 node v8.8.1 npm 5.4.2 全局安装下webpack.webpack-dev-serv ...
- 搭建一个webpack微服务器
[前言]:因为最近在vue2.0的时候用到了webpack的externals,才发现我之前都只是用webpack做一些搭建完项目后的“收尾工作”——即打包,而没有把它纳入到项目开发的“主体过程”中来 ...
- 做一个gulp+webpack+vue的单页应用开发架子
1.目标 最近项目上的事情不多,根据我自己的开发习惯,决定开发一些简单的开发架子,方便以后事情多的时候直接套用.本文讲的一个gulp+webpack+vue的单页应用架子,想要达到的目的: 可以通过命 ...
- 从零开始搭建一个简单的基于webpack的vue开发环境
原文地址:https://segmentfault.com/a/1190000012789253?utm_source=tag-newest 从零开始搭建一个简单的基于webpack的react开发环 ...
- 超详细动手搭建一个Vuepress站点及开启PWA与自动部署
超详细动手搭建一个Vuepress站点及开启PWA与自动部署 五一之前就想写一篇关于Vuepress的文章,结果朋友结婚就不了了之了. 记得最后一定要看注意事项! Vuepress介绍 官网:http ...
随机推荐
- C#中一些常用的方法使用
一.string.Empty string.Empty就相当于 "" ,一般用于字符串的初始化 , 比如: string a; Console.WriteLine(a);//这里会 ...
- 如何预测 Pinterest 和 Instagram 的未来发展潜力?
作者:陈琪链接:https://www.zhihu.com/question/20169268/answer/14229241来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出 ...
- P4148 简单题 k-d tree
思路:\(k-d\ tree\) 提交:2次 错因:整棵树重构时的严重错误:没有维护父子关系(之前写的是假重构所以没有维护父子关系) 题解: 遇到一个新的点就插进去,如果之前出现过就把权值加上. 代码 ...
- 016_linux驱动之_原子操作
1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作. 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0); //定义原子变量v并初始化为0 a ...
- 解决eslint与webstorm关于script标签的缩进问题
解决eslint与webstorm关于script标签的缩进问题 2018年12月29日 23:16:29 tozeroblog 阅读数 752 问题重现在vue-cli中,使用eslint时会对 ...
- python基础-跨域问题
跨域 -- 浏览器的同源策略 阻止ajax请求 不阻止src请求 -- jsonp -- 我们利用src发送请求 -- core -- class MyCore(MiddlewareMixin): d ...
- postman学习总结
从网上各处学习总结,会有不足之处,后期不断补充中... 一.get\post请求参数 1.get类型 (1)选择请求方式GET (2)输入完整的URL (3)在param中填写参数,点击send发送请 ...
- HDU 1074 Doing Homework ——(状态压缩DP)
考虑到n只有15,那么状压DP即可. 题目要求说输出字典序最小的答案的顺序,又考虑到题目给出的字符串本身字典序是递增的,那么枚举i的时候倒着来即可.因为在同样完成的情况下,后选字典序大的,小的字典序就 ...
- 基于Ryu REST API的VLAN实现
目录 0.预备知识 1.实验内容 2.编写脚本addflow.sh一步实现流表下发 3.使用api查看流表 4.实验结果 0.预备知识 ryu控制器的API文档:ryu.app.ofctl_rest ...
- Js中Array常用方法小结
说起Array的方法,不免让人皱一下眉头,下面我们从增删改查角度依次来总结. 1.增 push: 将传入的参数 ,插入数组的尾部,并返回新数组的长度.不管传入参数为一个值还是一个数组,都作为插入数组的 ...