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

news/2024/5/20 15:48:13/文章来源:https://blog.csdn.net/weixin_39826984/article/details/118486347

之前只知道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组件可以和页面分开放置。

多入口配置

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中可以这么引用导航和底部通栏

首页的内容在这里

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

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

npm install --save-dev html-withimg-loader

首页的内容在这里

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

react.png')%7D

支持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文件,类似这样

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:打包生产环境代码

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

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

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

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

相关文章

巧用ELK快速实现网站流量监控可视化

前言 本文可能不会详细记录每一步实现的过程&#xff0c;但一定程度上可以引领小伙伴走向更开阔的视野&#xff0c;串联每个环节&#xff0c;呈现予你不一样的效果。 业务规模 8个平台100台服务器10个集群分组微服务600用户N 面临问题 随着分布式微服务容器技术的发展&…

gpu服务器跑网站,gpu服务器跑深度学习

gpu服务器跑深度学习 内容精选换一换GPU加速型云服务器(GPU Accelerated Cloud Server, GACS)能够提供强大的浮点计算能力&#xff0c;从容应对高实时、高并发的海量计算场景。GPU加速型云服务器包括G系列和P系列两类。其中&#xff1a;G系列&#xff1a;图形加速型弹性云服务器…

如何通过优化主页大小,将网站大小减少 62%

什么是图像压缩&#xff1f; 压缩图像是指在保持可接受的视觉质量水平的同时减小图像文件的大小。我使用imagemin来压缩我网站上的图像。 要使用 imagemin&#xff0c;请确保已安装了 Node.js&#xff0c;然后打开终端窗口&#xff0c;cd 到项目的文件夹&#xff0c;并运行以…

5个常用的上传图片进行搜索的网站

1.http://www.tineye.com/ 最常用的图片搜索引擎&#xff0c;一般需要尽可能的接近原图的文件才能锁定图片网址&#xff0c;不过准确度极高。目前缺点是图片收录主要为欧美地区&#xff0c;而且收录量也不是很大。 2.http://www.gazopa.com/ 如图所示相似图片搜索&#xff0c;想…

一个知名网站的微服务架构最佳实现

译者语&#xff1a;如果你的项目正在从单体升级为微服务而忧心&#xff1b;或者你在实践微服务过程中手忙脚乱&#xff0c;本文都是你不容错过的好文。 微服务架构的目标是帮助工程团队更快、更安全、更高质量地交付产品。拆分服务允许团队快速迭代的同时&#xff0c;保证了对系…

创业之前,网站先行

可能你们还没有准备好向世人展示你们的产品&#xff0c;但你们可以先做一些前期工作&#xff0c;先为产品搭建个网站&#xff0c;做好形象工作。我并不是说创业公司都不可以在暗地里开发自己的产品&#xff0c;直到产品成型后才公之于众。但我觉得&#xff0c;如果你已经为你的…

IT创业失败案例解析 - 第四篇 (一家失败的招聘网站)

原文标题&#xff1a;My eHarmony for Hiring Failure&#xff08;查看原文推荐&#xff09; 原文作者&#xff1a;eHarmony 双语对照 前几天我通读了我最新博文的评论&#xff0c;它着实吸引了很多评论&#xff0c;像其他一些带有煽动性标题的文章一样&#xff0c;最终&#x…

linux 绑定域名到网站目录,教你绑定域名到你空间的子目录(亲测可用)

近日脑洞大开&#xff0c;Project Ai需要一个论坛&#xff0c;然而为了装逼优雅&#xff0c;我想用个二级域名绑定到我论坛。但万网的虚拟主机默认没绑定域名到子目录这个功能的.中间省略经过一番折腾后&#xff0c;我发现了一个方法(亲测万网可用)其实原理也很简单&#xff0c…

php网站程序哪个好,php的cms系统哪个好

php的cms系统哪个好&#xff1f;国内常见的CMS有dedecms、PHPCMS、WordPress、帝国cms、5UCMS等。相对较好的应该属帝国cms了。帝国cms非常老牌的CMS&#xff0c;就如同该CMS官网介绍的安全、强大、稳定、灵活。安全性&#xff1a;高&#xff0c;姜就是老的辣&#xff0c;老牌的…

【转载】一次面试引发的思考(中小型网站优化思考)

前言 故事的起因是这样的&#xff0c;由于本人地处偏僻工作地点在美丽的冰城哈尔滨虽然地方很美丽&#xff0c;但是这里的软件行业实在是算不上“美丽”&#xff0c;这么多年由于个人原因或者公司原因经常换工作&#xff0c;因为这里都是中小型公司&#xff0c;没有什么大公司。…

tp5网站 服务器部署,tp5云服务器部署

tp5云服务器部署 内容精选换一换SAP B1的部署方案如图1所示。说明如下&#xff1a;VPC网络&#xff1a;为了保证网络的安全&#xff0c;SAP B1系统中所有节点在一个VPC网络内&#xff0c;且所有节点应属于同一个AZ(Available Zone)。公网子网区&#xff1a;NAT(Network Address…

html 隐藏广告代码大全,JS广告代码_JS广告代码大全_js特效代码_js特效代码大全 - 懒人建站...

网站设置点击任何地方弹出新页面广告只弹出&#xff0c;可指定时间间隔。利用Cookie记忆&#xff0c;超过指定时间刷新页面广告会再次生效。参数说明&#xff1a; href:http://www.51xuediannao.com/, //链接地址&#xff0c;必须配置成你的地址 target:_blank, zIndex:9999999…

利用 IIS日志追查网站入侵者

<script type"text/javascript"></script> <script type"text/javascript" src"http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>以前黑站黑了很多&#xff0c;但是就没有想过会不会被追踪到&…

nginx配置多个ssl证书_给自己的网站主页配置ssl证书

使用https 可以防止数据在传输过程中产生一些不必要的泄露&#xff0c;未 的页面在经过ssl证书的签发后会变成https开头&#xff0c;下面记录一下配置https加密的整个过程购买域名首先第一步我们为了防止自己的公网ip暴露出去&#xff0c;需要给自己的网站设定一个全球唯一的域…

网站搭建教程(详细步骤)

文章目录网站组成一、服务器二、网站程序三、域名空间基本介绍网站空间如何购买空间&#xff08;云虚拟主机&#xff09;如何登陆服务器网站创建安装宝塔并配置信息云虚拟机安装宝塔修改账号密码安装软件创建站点上传程序创建多个链接网站组成 一、服务器 什么是服务器? 我…

25台服务器怎样支撑世界第54大网站

StackOverflow是一个IT技术问答网站&#xff0c;用户可以在网站上提交和回答问题。当下的StackOverflow已拥有400万个用户&#xff0c;4000万个回答&#xff0c;月PV5.6亿&#xff0c;世界排行第54。然而值得关注的是&#xff0c;支撑他们网站的全部服务器只有25台&#xff0c;…

华为云网站解析

来源&#xff1a;微信公众号「编程学习基地」 文章目录配置网站解析&#xff08;华为云注册域名&#xff09;操作流程步骤一&#xff1a;查看域名步骤二&#xff1a;为域名添加A记录集步骤三&#xff1a;为子域名添加A记录集配置网站解析&#xff08;华为云注册域名&#xff0…

码支付如何对接网站_扫码支付解决新方案——自助设备优先

前几天和朋友一起出去,在一个小摊贩哪里买东西,由于摊主的年纪较大,暂时不会弄二维码收款,我们出门又没带现金,所以我们只好到附近的自助售卖机上面去买饮料了。出乎意料的是附近的自助售卖机上面,竟然不支持二维码支付,还保留纸币和硬币的支付方式。小编很是吃惊!那么今天小编…

ourphp傲派企业建站系统如何对接短信功能?

OURPHP 可以快速、安全的开启一个大气、功能强大的企业网站,它不但可以帮助您的企业树立形象,还可以实现在您自已的官方网站上展开电子商务。OURPHP理论上支持创建世界上所有国家语言的网站&#xff0c;那么电商平台的短信功能如何接入呢&#xff1f;今天我们来分享下。 插件说…

python在线开发网站_Django开发在线教育网站1

Django的基本结构 现在&#xff0c;我们在使用Python进行网站开发的过程中&#xff0c;不可避免地会使用到Django框架&#xff1b;我们将从一个项目实战出发来熟悉Django整个开发的流程&#xff1b;便于让大家在项目开发的过程中&#xff0c;深入地理解Django的使用&#xff0c…