使用webpack从0搭建多入口网站脚手架,可复用导航栏/底部通栏/侧边栏,根据页面文件自动更改配置,支持ES6/Less...

news/2024/4/28 4:27:28/文章来源:https://blog.csdn.net/weixin_33853827/article/details/88731231

之前只知道webpack很强大,但是一直没有深入学习过,这次从头看了一下教程,然后从0开始搭建了一个多入口网站的开发脚手架,期间遇到过很多问题,所以有心整理一下,希望能给大家一点帮助。

多HTML网站使用webpack的必要性

假如我们接到这样一个任务,开发一个简单的官网,比如只有十几个html页面。项目很简单,我们没有必要使用什么大型框架,但是如果只是传统的写几个html、js和css,肯定会遇到这几个问题:

  • 网站导航和底部通栏是每个页面都共有的,如何实现复用?如果不复用,那么有改动的时候就要改n个页面,未免太傻
  • 如何在更改后强制清空用户缓存?我们不可能要求用户手动去清除浏览器缓存,那样太傻
  • 我想使用ES6进行js的开发,如何解决浏览器兼容性问题?
  • 我想使用less进行css样式开发,如何转换?

可以看出,没有自动化打包工具的加入,这些问题我们是很难解决的,因此使用webpack势在必行。

要实现的目标

看到这里,可能有的同学就急了,别废话,感觉进入正题吧,不!我们先定目标!无论做什么事情,都要先定目标,而不是干到哪里算哪里,这样是不会有大的提升的,正是在迈向目标的路上克服各种问题,我们才有进步,在进行这个脚手架搭建之前,我希望它是这样的

  • 能够打包成多个html文件和js文件,即支持多入口
  • 文件名称都要带上hash值,解决缓存问题
  • 能够复用网站的头部导航栏和底部通栏
  • 通过采用less进行样式的编写
  • 能够支持ES6开发
  • 用起来要方便,增加页面不需要手动去更改webpack的入口设置,希望能够根据目录下的文件自动配置
  • 不希望通过js动态插入css样式,这样会造成页面闪烁,希望html中直接引入css地址,就像平时开发那样
  • 能够实时看到开发的效果
  • build能够对代码进行压缩

好了,目标定了,开工

目录结构

别急,我们先来捋一捋目录,别着急写代码,一个好的目录,能让我们思路清晰,我的目录结构如下

+ config                    //环境变量配置文件,开发模式和生产模式使用不同的环境变量,比如接口地址,开发环境用的接口域名是http://a.com,生产环境使用的是http://b.com- dev.env.js            //本地开发变量   - prod.env.js           //生产环境变量
+ src                       + css                   //自己的less组件或者第三方css库+ component        //自己组件的less+ lib              //第三方的css库,比如bootstrap+ html                  //html代码,主要是一些模板,如头部导航,底部通栏,侧边栏+ tpl              //模板文件+ img                   //图片文件+ js                    //自己的js组件库或者第三方js库+ mod              //自己的js组件放这里+ lib              //第三方js库+ page                  //页面文件+ index            //这个根据自己情况设置,有的页面相关性强,可以放到一个文件夹下,比如一个user文件夹,可以放个人中心的所有页面- index.html   //每个页面都要有一个html- index.js     //每个页面都要有一个js,名称和html的名称保持一致- index.less   //每个页面都要有一个同名less文件+ test- test.html- test.js- test.less    + webpack                   //webpack的配置文件- dev-server.js        //开发服务设置,可以通过localhost访问页面,页面的实时编译- webpack.common.js    //开发环境和生产环境通用配置- webpack.dev.js       //开发环境特有的配置- webpack.prod.js      //生产环境特有的配置

首先是config目录,目前我主要放一些环境变量,就是开发环境和生产环境所不同的变量,比如接口地址,我们开发的时候,用本地的api接口地址,而打包的时候,要换成生产环境api地址。

webpack目录存放webpack的配置文件,其中开发和生产通用配置 放到webpack.common.js中,开发特有配置放到webpack.dev.js中,生产特有配置放到webpack.prod.js中。

src是我们开发的主目录,其中page目录放置我们的页面文件,这里可能和平时有所不同,我把每个页面用到的html、js和less文件放到了一起,有的同学可能把所有html放到一个目录下,js放到一个目录下,但是这样存在一个问题,每次改动页面,都要去翻目录,非常的不方便,我们应该把这种高度相关的文件放到一起,而提取的各种css组件或js组件可以和页面分开放置。

github地址:https://github.com/501351981/...

多入口配置

webpack支持多入口,即给定多个入口js文件,可以输出多个js文件,那么html怎么办呢?我希望开发过程是这样的,我在html中设置标题、SEO等信息,编写HTML内容代码,webpack把相关的js文件自动插入到html底部就行,可以的,这需要用到html-webpack-plugin 插件,可以通过调用html模板文件打包最终html。

安装html-webpack-plugin

npm install --save-dev html-webpack-plugin

webpack.common.js中多入口配置

const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports={entry:[index:'../src/page/index/index.js',test:'../src/page/test/test.js'],output: {filename: '[name].[hash].js',   //输出名称后面跟哈希值,解决缓存问题path: path.resolve(__dirname,'../dist')},....plugins: [new HtmlWebpackPlugin({filename: 'index.html',template: '../src/page/index/index.html',chunks: ['index'],})new HtmlWebpackPlugin({filename: 'test.html',template: '../src/page/test/test.html',chunks: ['test'],})]
}

这样设置存在一个问题,每次新增一个页面,我就要到这里添加一下,未免很麻烦,我们其实可以通过读取 src/page下的js文件,自动加入入口配置;读取 src/page下的所有html文件,自动调用new HtmlWebpackPlugin进行实例化。

读取目录下所有文件名,我们需要引入glob,先安装

npm install --save-dev glob

改进后的配置

const glob = require('glob')
const CleanWebpackPlugin = require('clean-webpack-plugin');//多入口js的配置,读取src/page下所有的js文件
function entries() {let jsDir = path.resolve(__dirname, '../src/page')let entryFiles = glob.sync(jsDir + '/**/*.js')let map = {};for (let i = 0; i < entryFiles.length; i++) {let filePath = entryFiles[i];let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));map[filename] = filePath;}return map;
}//读取多个html模板,进行插件实例化
function newHtmlWebpackPlugins(){let jsDir = path.resolve(__dirname, '../src/page')let htmls = glob.sync(jsDir + '/**/*.html')let plugins=[]for (let i = 0; i < htmls.length; i++) {let filePath = htmls[i];let filename_no_extension = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.'));let filename=filename_no_extension.concat('.html')plugins.push(new HtmlWebpackPlugin({filename: filename,template: filePath,chunks: [filename_no_extension],}))}return plugins
}module.exports={entry:entries(),output: {filename: '[name].[hash].js',path: path.resolve(__dirname,'../dist')},....plugins: [...newHtmlWebpackPlugins()]
}

好了,现在新增页面不需要更改webpack配置了,只需要重新运行一下 npm run start即可

共有头部和底部的复用

头部导航和底部通栏我们各个页面都是一样的,因此需要引入,那么html中怎么引入另一个html呢,这需要用到raw-loader 或 html-withimg-loader

安装raw-loader,raw-loader可以加载文件原始内容(utf-8格式)

npm install --save-dev raw-loader
//目录结构+ src                       + html                  + tpl              - navbar.html  //共用的头部导航  - footer.html  //共用的底部导航+ page                  //页面文件+ index            - index.html   + test- test.html

我们在index.html中可以这么引用导航和底部通栏

<!--引入通用的导航部分-->
<%=require('raw-loader!../../html/tpl/navbar.html')%><!--页面的正式内容在这里-->
<div id="app"><p>首页的内容在这里</p>
</div><!--引入通用的底部栏-->
<%=require('raw-loader!../../html/tpl/footer.html')%>

最初我在查找解决方案的时候,看到文章推荐使用raw-loader,但是发现这样存在一个问题,就是导航中无法引用本地的图片,比如导航中引用一个logo图片,是找不到的,因为我们打包的时候也会对图片进行处理,后面添加hash值,直接写图片路径是不行的,后来我改用 html-withimg-loader解决了

安装html-withimg-loader,顾名思义,这个插件可以加载带有图片的html

npm install --save-dev html-withimg-loader
<!--引入通用的导航部分-->
<%=require('html-withimg-loader!../../html/tpl/navbar.html')%><!--页面的正式内容在这里-->
<div id="app"><p>首页的内容在这里</p>
</div><!--引入通用的底部栏-->
<%=require('html-withimg-loader!../../html/tpl/footer.html')%>

顺便提一句,html中引用图片地址是需要这样写的,需要通过require才行,简单的填写图片地址是不行的

<img src="${require('../../img/react.png')}" width="50" height="50">

支持ES6编写js

相信大家现在都已经学过ES6了,可是鉴于浏览器的兼容性,还没法随心所欲的用,需要插件支持,我们首先安装

npm install --save-dev babel-loader babel-core babel-preset-env

添加webpack配置

webpack.common.js,我们只对src目录下的js进行转换

{test: /\.js$/,use: {loader: 'babel-loader'},include: path.resolve(__dirname,'../src')
},

同时在项目目录下添加一个名为.babelrc的文件,对babel进行设置,支持占有率大于1%的浏览器的最近2个版本

{"presets": [["env",{"targets": {"browsers": ["> 1%", "last 2 versions"]}}]],
}

babel只是将ES6语法转为ES5的语法,比如箭头函数转为function(){},但是对一些ES6特有的功能没有转换,比如new Map(),打包之后还是new Map(),我们还需要再安装一个插件,完成这个转换工作。

npm install --save-dev babel-plugin-transform-runtime

更改.babelrc文件

{"presets": [["env",{"targets": {"browsers": ["> 1%", "last 2 versions"]}}]],"plugins": ["transform-runtime"]    //引入插件
}

现在可以放心大胆的使用ES6了

使用Less编写样式

首先还是安装相关插件

npm install --save-dev less less-loader css-loader style-loader

webpack.common.js配置

{test: /\.css$/,use:["style-loader","css-loader","less-loader"]
},

在index.js文件中,我们就可以这样引入less文件了

import './index.less'

打包之后,运行html页面,index.js会动态把css样式插入到html页面,这样会造成一个问题,刚加载html的时候是一个样式,js插入css样式后是另一个样式,造成页面闪烁一下,体验不好(技术也要追求用户体验啊,不光是产品经理的事)。这有两个解决方案吧,第一个就是在JS未加载完成之前,显示一个loading动画,把整个页面遮盖住,第二个就是把css文件路径打包进html中,不要通过js动态添加,我选用的第二个方案。

我们要把less文件打包到一个css文件中,需要用到插件extract-text-webpack-plugin

npm install --save-dev extract-text-webpack-plugin

webpack.common.js

const ExtractTextPlugin = require("extract-text-webpack-plugin");module.exports={rules: [{test: /\.less$/,use: ExtractTextPlugin.extract({fallback: "style-loader",use: "css-loader!less-loader"})},]
}plugins: [new ExtractTextPlugin("[name].[hash:8].css"),
]

这样打包之后的html中会引入css文件,类似这样

<link href="index.5eb2501d.css" rel="stylesheet">

webpack配置

实际在我从0开始搭建的过程中,是先进行webpack这块的配置的,之所以放到最后是不想影响主干内容,下面我们也简单介绍一下我的webpack配置。

webpack官方推荐不写重复的配置,即把本地和生产环境共用的配置放到一个文件,然后通过merge进行合并

webpack.dev.js

const webpack = require('webpack');
const merge = require('webpack-merge');
const common = require('./webpack.common');var OpenBrowserPlugin = require('open-browser-webpack-plugin');const env=require("../config/dev.env")module.exports=merge(common,{mode:"development",devtool: 'inline-source-map',plugins:[new webpack.DefinePlugin({'process.env': env}),new webpack.NamedModulesPlugin(),new webpack.HotModuleReplacementPlugin(),new OpenBrowserPlugin({ url: 'http://localhost:5000' })],
})

我们可以看到,通过webpack-merge插件,将共用配置webpack.common.js和开发的配置进行合并

new webpack.DefinePlugin({'process.env': env}),

DefinePlugin定义了全局变量process.env

new OpenBrowserPlugin({ url: 'http://localhost:5000' })

这个插件是为了在我们允许npm run start后,自动打开页面http://localhost:5000,避免每次都手动打开。
webpack-dev-server 为我们提供了一个简单的 web 服务器,并且能够实时重新加载,让我们可以实时看到开发结果,关于web服务器的配置,我放到了dev-server.js中

const webpackDevServer = require('webpack-dev-server');
const webpack = require('webpack');const config = require('./webpack.dev');
const options = {contentBase: './dist',hot: true,host: 'localhost',
};webpackDevServer.addDevServerEntrypoints(config, options);
const compiler = webpack(config);
const server = new webpackDevServer(compiler, options);server.listen(5000, 'localhost', () => {console.log('dev server listening on port 5000');
});

在package.json中,我们添加两个脚本

"scripts": {"start": "node webpack/dev-server.js","build": "npx webpack --config webpack/webpack.prod.js",
},

这样我们就可以在命令行输入两个命令

npm run start :进入开发模式

npm run build:打包生产环境代码

好了,基本上把我做的这个脚手架介绍完了,实际要理解还需要自己去试,看是一回事,做出来又是另一回事,给别人讲明白那就更不容易了,前端路漫漫,大家努力吧。

github地址:https://github.com/501351981/...

这个脚手架还不完善,不过基本够用了,后面我还会再做几个脚手架,比如结合vue进行多页面开发或移动端H5开发,有兴趣可以持续关注。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_722263.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php影院影城源码,99影院源码 影视网站程序源码/附教程

99影院源码 影视网站程序源码/附教程API站点环境要求API是TP5框架&#xff0c;CMS是苹果cms10(TP框架)API(视频接口管理后台)及CMS(苹果cms或其他影视站点)是两个站点&#xff0c;需要用两个域名或子域名创建运行环境服务器安装 宝塔面板 (相关安装教程参照宝塔面板官方教程…

amp模板展示amp网站也可以做得很好看

ytkah比较喜欢研究一些新东西&#xff0c;AMP刚出来的时候就上手了&#xff0c;也做了一些站点&#xff0c;而且还不赖&#xff0c;因为这个还机缘巧合参加了深圳的谷歌全球合作伙伴大会&#xff0c;很多大牛也都来了&#xff0c;很荣幸能和他们一起交流。下面就稍微展示一下am…

自适应屏幕的jQuery响应式布局网站特效代码

jQuery响应式图片九宫格布局点击图片查看大图效果代码 jquery响应式布局_宽屏响应式焦点图片动画轮播代码 css3绘图制作css3响应式组织架构图形代码 jQuery css3图片翻转响应式布局翻转图片筛选器代码 jquery html5响应式幻灯片插件网站响应式全屏幻灯片轮播代码 jQuery响应式焦…

淘宝、知乎、豆瓣......18个网站的Python爬虫登录汇总,都在这个开源项目里

2019独角兽企业重金招聘Python工程师标准>>> 如果你从事数据科学领域&#xff0c;那么获取数据对于你来说就不可或缺&#xff0c;网络爬虫这一关你必须得过&#xff0c;而说到爬虫&#xff0c;大多数人想到的就是Python&#xff0c;因为python不仅编写调试方便&…

网站样式推荐

一、easyui&#xff08;不建议&#xff0c;有大量的ajax&#xff0c;不容易修改&#xff09; 使用步骤 1、下载http://www.jeasyui.net/download/jquery.html 2、使用deom&#xff1a;去下载文件中找&#xff08;更全&#xff09;或http://www.jeasyui.net/demo/380.html并且复…

电信网为不能访问联通服务器的网站_新加坡服务器机房怎么样?

租用新加坡服务器的可能不是新加坡人&#xff0c;但可能是在当地出差和生活的国人。那亚太机房中&#xff0c;新加坡服务器怎么样呢?如果从全国各地各线路的Ping值测试结果来看&#xff0c;其新加坡机房的ping值也处于中位徘徊&#xff0c;目前天下数据CN2优化双向直连新加坡服…

favicon自动获取_php获取网站favicon.ico图标 api源码 自动获取并添加Favicon图标

通常情况下&#xff0c;做网站的都会给自己的网站添加一个Icon&#xff0c;浏览器上一长排的标签页&#xff0c;用Icon来区分就显得更加醒目。现在想找一个没有Icon的网站并不好找&#xff0c;可见没有Icon的网站是多么的业余啊。"什么&#xff1f;你问Icon是什么&#xf…

自定义鼠标指针轨迹_精美网站鼠标指针,你见过多少?

之前推荐了些 Windows 指针&#xff0c;适用于安装了的电脑改变指针样式。松鼠小&#xff1a;酷炫 Windows 鼠标指针&#xff01;​zhuanlan.zhihu.com其实网站是可改变访问者的指针&#xff0c;实现方式大致有两种&#xff0c;其一是代码法。优点是可灵活自定义两种样式&#…

云服务器建站原理_使用香港云服务器建站有什么优势?

香港云服务器是急于开通网站的站长和外贸企业网站经常选用的产品&#xff0c;香港云服务器有其自身独特的优势。带宽和线路优势香港作为互联网光缆出口之一&#xff0c;机房使用国际带宽&#xff0c;宽带输出量巨大。香港云服务器不存在电信和联通不互通的问题&#xff0c;所以…

wordpress建立php站点地图,WordPress创建站点地图并提交到百度和谷歌

发现没有被google收录完整页面&#xff0c;所以有了这篇文章。创建文件第一步在网站根目录创建文件xmlmap.php生成静态文件编辑.htaccess&#xff0c;确认有下面配置节&#xff0c;原来的不要删掉。访问测试访问页面源码&#xff1a;提交百度和谷歌进入你的网站链接&#xff0c…

html电商app小图标素材,20套购物网站专用的图标素材包

20套购物网站专用的图标素材包8月 6, 2015评论Sponsor随着移动互联网的使用率增加&#xff0c;电子商务行业也趁着这机会加入到移动端&#xff0c;连外卖网这些也越来越多了&#xff0c;所以电子商务相关的素材是不能少的&#xff0c;为了方便新人和节省设计时间&#xff0c;可…

影视网站云服务器,影视网站云服务器

影视网站云服务器 内容精选换一换云解析服务支持为域名快速添加网站解析&#xff0c;通过该功能可以简化解析记录的配置&#xff0c;包含如下两种场景&#xff1a;网站解析至IP地址&#xff1a;为域名的主域名和子域名分别添加一条A类型记录集网站解析至另一域名&#xff1a;为…

wap建站系统开源_Shopify月租贵?这些开源建站工具你会用吗?

提到独立站就会说到shopify&#xff0c;好多新手跟我反映能不能不用shopify建站&#xff0c;第一点就是觉得月租贵。shopify只是一个建站工具&#xff0c;帮助我们搭建网站的工具还有很多&#xff0c;那究竟要不要用shopify去建站呢&#xff1f;这篇文章帮你深度分析一下各大建…

长尾词推广系统推荐乐云seo_如何挖掘关键词?分享5招,小白也能做好SEO网站优化!...

SEO优化、提升排名、网站优化这些都是SEO网站推广人员老生常谈的话题。关于网站SEO优化的咨询&#xff0c;很多人会遇到以下几种情况&#xff1a;网站优化很吃力&#xff1b;网站排名总是上不去&#xff1b;网站排名不稳定该怎么解决&#xff1b;不知道如何挑选合适的网站关键词…

Docker 用存储卷部署Apache网站

用存储卷部署一个网站 //创建容器 [rootlocalhost ~]# docker run --name centos -dit centos /bin/bash 4aceab993d472d30ff93a09a1b70c47f31b17324ad9b0d269f590e48b13d8e85[rootlocalhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATU…

Docker 用Dockerfile部署Apache网站

Dockerfile部署Apache网站基于Centos编写Apache的Dockerfile基于Alpine 编写Apache的Dockerfile&#xff08;精简版&#xff09;基于Centos编写Apache的Dockerfile //创建apache服务的dockerfile文件目录 [rootlocalhost ~]# mkdir httpd/files -p//上传源码包 [rootlocalhost…

网博士自助建站系统_浅析企业自助建站系统的特性

在第三代企业网站建设浪潮掀起之前自主式系统的出现既省时省力还省钱&#xff0c;因此大家对于应用之后二十分钟就可以出现一个功能完善且精致美观的网址有很大的好感。但是这类可以推动现代化建设的产品也需要让大家了解一下它的方方面面&#xff0c;那么它的其他层面特性该怎…

前端不同服务器之间的通信_网页?服务器?http协议?网站?前端开发工具?...

一、什么是http协议?什么是协议&#xff0c;就是一群人协商好了&#xff0c;统一认知的规则。【例】你&#xff0c;我&#xff0c;他&#xff0c;还有她他他&#xff0c;大家一致认定结婚的时候都要给份子钱&#xff0c;这种大家认同的就是协议。http协议&#xff0c;就规定了…

RPM包管理工具的常规命令及网站发布

RPM包管理工具的常规命令及网站发布前言一.Linux安装软件和程序的三种方式1.rpm包管理工具2.yun源3.源码安装二..典型应用程序的目录结构三.常见的软件包封装类型四.RPM包管理工具及包格式五.RPM包的下载&#xff0c;网站发布5.1挂载镜像光盘5.2安装软件以及RPM常用命令5.3启动…