webpack单页面项目与多页面项目学习搭建

webpack的配置项与单页面

举个例子 => 你有这样一个项目架构

├── config
│	├── webpack.config.js //webpack配置文件
├── src
│  └── view //页面部分
│ 	├── router //项目的路由
│	├── reducer //项目的redux仓库
│	└── app.js //项目的入口文件
├── public
│   └── index.html //入口文件最后注入到的html
└── package.json //依赖的版本信息及运行项目的信息

入口(entry)

entry可以接收多种类型的值,字符串、数组、对象。简单来说entry包含的值代表着一个react项目的根js文件(也就是create-react-app脚手架创建的项目当中的app.js文件)

相对来说对象形式是扩展性最大,可以包含多入口的js文件,也可以定义入口文件的name
浏览器加载的资源

//webpack.config.js
module.exports = {
	entry: {
		app: './src/index.js', //想要的入口文件名称 : 入口文件路径
	}
}
!!! 请注意入口路径(这个相对路径不是对于当前文件来说的,目前的感觉是这个相对路径是相对于webpack.config.js被执行的路径来说的)

webpack模块解析当中有对于相对路径写法解析的解释 以及
这里贴一下我的package.json中起项目的部分
在这里插入图片描述
在这里插入图片描述
这是我目前对于为什么在webpack.config.js当中仍然可以使用./src/index.js来搜寻入口文件的原因 => 否则./src/index.js的路径应该指向的是config当中

出口(output)

webpack中对于出口的最低要求是对象类型的值,并且对象当中有一个filename来表示构建完成之后输出的文件的名字.

//webpack.config.js
module.exports = {
	output: {
		filename: 'app', //filename : 最终构建好的文件的名称
	}
}

但是你一想,哎呀我entry中已经写上了我想要的出口文件的名称,这里再重复一下不是吃饱了吗,那么你可以用下面这种方式节省体力

//webpack.config.js
module.exports = {
	output: {
		filename: '[name].js', // name这里填入的值就是你在entry以对象形式创建的属性名
	}
}

下面是output的其他属性(以后用到回来补充)

//webpack.config.js
module.exports = {
	output: {
		filename: '[name].js', // name这里填入的值就是你在entry以对象形式创建的属性名
		path: __dirname + '/dist', //path: 你构建好后的文件存放的路径及文件夹名称
		//__dirname是当前文件的所在文件夹的绝对路径 => 如果你想构建在别的地方可以结合着path.join()的方式 => path.join(__dirname, '..', 'dist')这样就会将dist文件夹构建在项目的根目录下而不是构建在config文件夹当中
	}
}

转换规则loader(module)

下面是一个例子 => 这些转换loader就是帮助在构建的时候将浏览器不能支持的es的新语法或者scss等进行转义
https://www.webpackjs.com/loaders

module: {
     rules: [
         {
             test: /\.js$/, //目标文件
             exclude: /node_modules/, //排除的文件
             use: [ //object[] => object是loader配置项,可以包含多个转换规则(webpack中的解释是多个loader会从右到左(或从下到上)地取值)
                 {
                     loader: 'babel-loader',  //babel不陌生吧,最初用来将js中的es6的语法进行转换
                     options: { //可以包含对应loader的配置项
                         presets: ['@babel/preset-react'], //如果没有记错的话这里应该是配置loader对应的解析器 
                         //https://babeljs.io/docs/en/presets
                     },
                 },
             ],
         },
     ],
}

像ts、scss、(png、jpg)这样的文件后缀都可以通过配置相应的loader进行辅助编译

插件(plugins)

webpack给出的解释: 插件的目的在于解决 loader 无法实现的其他事
用法: 由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入一个 new 实例

module.export = {
	plugins: [new HtmlWebpackPlugin({ template: './public/index.html' })] // (new 构造函数)[]
	//因为接收的是new 构造函数 => 因此可以传入一些满足构造函数要求的参数进去
}
//到这里为止基本就实现了本文的第一张图片中(当然你肯定要启动webpack的配置文件 => 第二张图片)
<script type="text/javascript" src="/app.js"></script>

解析(resolve)

resolve : 可以设置一些模块如何被解析

module.export = {
	resolve: {
		 alias: {
            '@': path.resolve(__dirname, '..', 'src'), 
            //或者这样写 '@': '/src' => webpack默认会将相对路径与上下文路径进行拼接 => 上下文路径默认就是node运行是的路径 => 对于我来说就是E:node\前端项目\src
        },
        extensions: ['.js', '.json', '.ts', '.tsx'], //告诉webpack你引入的文件要寻找哪些后缀的 => 简单来说就是你../index但没有说明是什么后缀的文件(你不设置这里的话好像只会找后缀为js的文件)。
	}
}

对于这个配置项还有很多(目前还没有接触到,先贴个官网链接,用到的时候再来添加)
在这里插入图片描述在这里插入图片描述

devServer配置项

可以通过对devServer的配置来修改webpack-dev-server的一些行为

devServer: {
      historyApiFallback: true, //开启使用h5的history API
      proxy: {
      	  //可以监听以/api开头的请求
          '/api': {
              //将请求的host替换成http://localhost:3001
              target: 'http://localhost:3001',
              //去掉/api
              pathRewrite: { '^/api': '' },
          },
      },
      hot: true,
      port: 3000, //可以指定你的项目的端口号
},

进行到这里,单页面项目的webpack构建已经基本完成了

webpack多页面

同样有一个这样的项目

├── config
│	├── webpack.config.js //webpack配置文件
├── src
│  	└── view
│ 	├── router
│	├── reducer
│	└── entry //多项目所有的入口文件
│		└── user.js
│		├── controller.js
│		└── sign.js
├── public //入口文件最后注入到的html
│   └── user.html 
│	├── controller.html
│	└── sign.html
└── package.json //依赖的版本信息及运行项目的信息
//webpack的配置文件
const app = (function(){
	const pageModule = ['user', 'controller', 'sign'];
	const appEntry = pageModule.reducer((pv, cv) => {
		pv[cv] = `./src/entry/${cv}.js`;
		return pv;
	}, {})
	const appHtml = pageModule.reducer((pv, cv) => {
		const htmlOption = {
			template: `./public/${cv}.html`  //当然new HtmlWebpackPlugin可以接收的参数也不止这一个
			chunk: [cv], //当前html页面要包含的js文件
		}
		pv.push(new HtmlWebpackPlugin(htmlOption))
		return pv
	}, [])
	return {
		appEntry,
		appHtml
	}
})()
module.exports = {
	entry : app.appEntry, //入口文件的名字与读取的文件位置设置完成
	output: {
		filename: '[name].js',
		path: path.join(__dirname, '..', '/dist'),
	}
	plugins: app.appHtml,
	rules: {}, //解析规则
	devServer: {
		historyApiFallback: {
			rewrites: [{from: /\/rn\/.*$/, to: '/index.html'}]// 可以接收一个数组 => 这一部分紧跟在后面
			//这个配置项是支持多页面构建的重要部分
		}
		proxy: {
            '/api': {
                target: 'http://localhost:3001',
                pathRewrite: { '^/api': '' },
            },
        },
	},
}

rewrites

//先写一个例子 => 后面会结合我自己的项目的图片
devServer: {
	historyApiFallback: {
		rewrites: [
			{from: /\/rn\/.*$/, to: '/index.html'} 
			//这里有一个疑惑的地方就是/index.html是不是打包后的dist文件夹下的html文件,
			//如果是那这里的/index.html是怎样的一个路径,
			//因为对于我当前的项目结构来说除了这样写to的冲定向路径外,像'index.html或者'./dist/html都会失败'
		]
	}
},
  1. devServer中设置对url的重定向

在这里插入图片描述

在这里插入图片描述
请添加图片描述
有人可能会问了,你这里都写上了路由的路径了,当然可以访问到了
截止到现在的理解(可能会有错误),当使用history路由的时候,其实本质是get请求,但是你的项目中的路由路径并不是真正的请求的资源地址,当你使用了history路由之后,如果不做对应的配置处理,就很容易报错显示资源不存在=>这个时候就是你以为的路由路径其实是做了get请求资源(没有找到这个资源就提示资源不存在拉)。

下面我把devServer中的重定向去掉再来看一下

  1. devServer中不设置重定向

在这里插入图片描述在这里插入图片描述
在这里插入图片描述可以看到上面这张图片就很明显的提示这个get请求 /rn/select这个资源路径不存在
但是为啥下面的这个可以正常显示呢,你应该也注意到这个左边的导航栏了吧,不要忘记了这个是通过点击导航栏触发路由跳转过来。如果你使用了history路由,不妨试着刷新一下页面,看看是不是报get请求资源不存在
在这里插入图片描述

  1. devServer的rewrites属性只是帮助开发者在开发模式下将特定规则的get请求重定向到对应的入口html页面
    从下面这张图上可以看出/rn/select已经成功以index.html来作为入口页面了
    在这里插入图片描述
  2. 经过rewrites重定后,就能在匹配到你想要的入口中所对应的页面(这里路由匹配可能因为实现情况不同而有所不同,下面是我对当前这个项目结构下做的处理)
    在这里插入图片描述
    在这里插入图片描述

到了这里,我们解决了两个问题。一是history路由下刷新页面显示变成get请求资源导致页面丢失。二是多入口打包后对应模块的路由如何加载对应的打包好后的入口html页面(当然这只是在开发的时候可以使用的方式,因为打包到线上后是没有办法使用的,这个时候要后端做处理) =》 学到后再来补充

其它配置项补充

externals

从依赖中剔除所写目标,阻止将某些 import 的包(package)打包到 bundle 中,而是在运行时从外部获取这些依赖(.html下面增加script标签进行引入) => 在调试react最初的源码而非编译产生的development文件时可以使用该方式
在这里插入图片描述

https://webpack.docschina.org/configuration/externals#root(官网介绍)

没有排除之前,函数调用栈都是development.js
在这里插入图片描述
排除之后,再看调试时的函数调用栈
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值