打包多页应用
一个项目中可能有多个页面,每个页面都会引入不同的资源文件
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
//多入口
entry: {
home: './src/index.js',
other: './src/other.js'
},
mode: 'development',
//多出口
output: {
//[name] home,other
filename: '[name].js', //会生成home.js 和other.js
path: path.resolve(__dirname, 'out')
},
devServer: {
port: 3000,
contentBase: './out',
progress: true
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'home.html',
chunks: ['home'] //代码块 home引用home的 other引用other的
}),
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'other.html',
chunks: ['other']
})
]
}
source-map
在我们项目装换为生产模式的时候,我们知道js文件会被压缩,此时如果有什么报错,错误信息将指向第一行(因为压缩后它就一行emmm)。这样很不便于我们调试。于是出现了source-map
文件映射,即使代码压缩了,他也会映射出源文件中的错误位置,接下来对四种source-map做出对比
devtool是webpack.config.js下的配置项,与module并列
// 1)源码映射 会生成单独的一个sourcemap文件 出错了 会标识 当前报错的列和行 大而全
devtool: 'source-map' // 增加映射文件可以帮助我们调试代码
// 2) 不会产生单独的文件 集成在代码中,但是可以显示行和列
devtool: 'eval-source-map'
// 3) 不会产生列 但是是一个单独的映射文件
devtool: 'cheap-module-source-map' //产生后可保存起来
// 4) 不会产生文件 继承在打包后的文件中 不会产生列
devtool: 'cheap-module-eval-source-map'
效果(cheap-module-eval-source-map)
实时监控watch
我们每次更改完代码之后都要npm run build
,这样做很麻烦,于是我们使用watch
实时监控代码改变
每次保存后自动帮我们打包
watch: true, //实时监控
watchOptions: { // 监控的选项
poll: 1000, //每秒询问1000次,
aggregateTimeout: 500, //防抖 一直输入代码停下500ms后才打包 ,而不是输入一下打包一下
ignored: /node_modules/ //不需要监控该文件
}
三个webpack常用插件
clean-webpack-plugin
打包之前清除输出目录中的内容
copy-webpack-plugin
打包时将某文件的内容复制到另一个文件中
BannerPlugin
版权声明
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
。。。
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new CleanWebpackPlugin(),
new CopyWebpackPlugin([{
from: './doc',
to: './'
}]),
new webpack.BannerPlugin('lheng 2019-8-2')
],
webpack 解决跨域问题
- 服务端在一个端口上,webpack在一个端口上
- 前端mock数据,不需要服务端参与(都在webpack开启的端口上)
- 服务端开启webpack,使二者在同一端口上(都在服务端端口上)
1. 服务端在一个端口上,webpack在一个端口上
开启一个服务端,webpack自带express,同时devServer本身就是一个express
- server.js
const express = require('express')
const app = express()
app.get('/api/user', (req, res) => {
res.json({ name: 'lheng', age: 18 })
})
app.listen(3000, () => {
console.log('server start');
})
-node server.js,开启服务端
前端ajax请求
import $ from 'jquery'
$.get('/api/user', (data) => {
console.log(data);
})
})
在webpack.config.js
中配置代理
devServer:{
proxy: {
'/api': 'http://localhost:3000'
}
}
npm run dev
默认运行在8080端口,而服务端运行在3000端口,这样会跨域,使用代理解决跨域
但是在实际开发中,后端人员书写api不会一直以/api
开头,那么我们在proxy
中就要写好多条,这样做很繁琐,接下来我们看看如果api开头种类很多的解决方案
- server.js
const express = require('express')
const app = express()
app.get('/user', (req, res) => {
res.json({ name: 'lheng', age: 18 })
})
app.get('/book', (req, res) => {
res.json({ name: 'book', age: 18 })
})
app.listen(3000, () => {
console.log('server start');
})
前端请求时依旧使用/api
开头
import $ from 'jquery'
$.get('/api/user', (data) => {
console.log(data);
})
$.get('/api/book', (data) => {
console.log(data);
})
webpack.config.js
中proxy做出改变
devServer: {
proxy: {//重写的方式,把请求代理到express服务器上
'/api': {
target: 'http://localhost:3000',
pathRewrite: {//必须是对象
'/api': ''
}
}
}
},
2. 前端mock数据,不需要服务端参与(都在webpack开启的端口上)
有的时候我们前端只是想mock一些数据,并不需要服务端的参与,之前我们提到过,webpack-dev-server
本身就是一个express
,我们可以直接在devServer中书写api
-index.js
import $ from 'jquery'
$.get('/user', (data) => {
console.log(data);
})
-webpack.config.js
devServer: {
before(app) { //webpack提供的方法,启动前调用
app.get('/user', (req, res) => {
res.json({ msg: 'succ' })
})
}
},
这样会在启动webpack之前先启动内置的express服务器(也就是启动我们的api接口),这样就实现了在前端的端口上访问到我们mock的数据
3. 服务端开启webpack,使二者在同一端口上(都在服务端端口上)
说完共同运行在前端的端口上,接下来我们试试将webpack运行在服务端,这一要使用到一个插件webpack-dev-middleware
,它将会作为中间件来使用
-server.js
const express = require('express')
const app = express()
let webpack = require('webpack')
let middle = require('webpack-dev-middleware')
let config = require('./webpack.config')
let compiler = webpack(config)
app.use(middle(compiler))
app.get('/user', (req, res) => {
res.json({ name: 'lheng', age: 18 })
})
app.get('/book', (req, res) => {
res.json({ name: 'book', age: 18 })
})
app.listen(3000, () => {
console.log('server start');
})
启动时运行node server.js
即可在开启服务端同时打包项目,这样二者就可以运行在统一端口上,避免跨域问题
在这个过程中遇到了一个小问题
我之前的server.js
是放在src
下的,这样以来require('../weboack.config.js)
后config文件中的entry
中的路径就有点问题
entry: './src/index.js',
由于server位于src下,配置文件就会以src作为当前目录,这样就会导致查找失败。而我们的webpack启动时是以项目根目录作为当前目录的,所以就可以找到src。因此为了两边都可以打包成功,server.js
应该放在src之外。问题解决~
报错信息:
ERROR in Entry module not found: Error: Can't resolve './src/index.js' in 'C:\xxxxx\Desktop\webpackT2\src'