webpack高级配置与优化详解(2)

module.exports = { watch: true, watchOptions: { poll: 1000, // 每隔一秒轮询一次文件是否发生变化 aggregateTimeout: 1000, // 当第一个文件更改,会在重新构建前增加延迟。这个选项允许 webpack 将这段时间内进行的任何其他更改都聚合到一次重新构建里 ignored: /node_modules/ // 排除一些文件的监听 } }

四、三个常见小插件的使用

1、clean-webpack-plugin: 其作用就是每次打包前先先将输出目录中的内容进行清空,然后再将打包输出的文件输出到输出目录中。

const {CleanWebpackPlugin} = require("clean-webpack-plugin"); module.exports = { plugins: [ new CleanWebpackPlugin() // 打包前清空输出目录 ] }

需要注意的是,require("clean-webpack-plugin)的结果是一个对象而不是类,这个对象中的 CleanWebpackPlugin 属性才是一个类,我们就是用这个类去创建插件对象。

2、copy-webpack-plugin: 其作用就是打包的时候带上一些 readMe.md、history.md 等等一起输出到输出目录中。

module.exports = { plugins: [ new CopyWebpackPlugin([ { from: "./readMe.md", // 将项目根目录下的readMe.md文件一起拷贝到输出目录中 to: "" // 属性值为空字符串则表示是输出目录 } ]) ] }

3、BannerPlugin: 其作用就是在打包输出的 js 文件的头部添加一些文字注释,比如版权说明等等,BannerPlugin 是 webpack 内置的插件,如:

module.exports = { plugins: [ new webpack.BannerPlugin("Copyright © 2019") // 在js文件头部添加版权说明 ] }

五、webpack 跨域问题

为什么 webpack 会存在跨域问题?因为 webpack 打包的是前端代码,其最终会被部署到前端服务器上,而前后端代码通常部署在不同的服务器上,即使是部署在同一个服务器上,所使用的端口也是不一样的,当前端代码通过 ajax 等手段向后端服务器获取数据的时候,由于前后端代码不在同一个域中,故存在跨域问题。

比如,我们通过 webpack 的 devServer 来运行部署我们的前端应用代码,devServer 启动在 8080 端口上,而前端应用代码中会通过 ajax 请求后端数据,后端服务器启动在 3000 端口上。

// index.js const xhr = new XMLHttpRequest(); // xhr.open("get", "http://localhost:3000/api/test"); // 由于跨域问题无法直接访问到:3000下的资源 xhr.open("get", "/api/test"); // 本来是要访问:3000/api/test xhr.onreadystatechange = () => { if (xhr.readyState === 4) { console.log(xhr.responseText); } } xhr.send();

由于前端代码是运行在浏览器中的,如果在前端代码中直接通过 ajax 向:3000/api/test 发起请求获取数据,那么由于浏览器同源策略的影响,会存在跨域的问题,所以必须访问 /api/test。但是这样访问又会出现 404 问题,因为其实访问的是 :8080/api/test,8080 服务器上是没有该资源的,解决办法就是通过 devServer 配置一个代理服务器

module.exports = { devServer: { proxy: { "/api": "http://localhost:3000" // 路径以/api开头则代理到localhost:3000上 } } }

访问 :8080/api/test 

就会被代理到:3000/api/test 上,proxy 还支持路径的重写,如果 3000 端口服务器上并没有 /api/test 路径,只有 /test 路径,那么就可以对路径进行重写,将 /api 替换掉

module.exports = { devServer: { proxy: { "/api": { target: "http://localhost:3000", pathRewrite: {"/api": ""} // 将/api替换掉 } } } }

访问 :8080/api/test 

就会被代理到 :3000/test 上

如果前端只是想 mock 一些数据,并不需要真正的去访问后台服务器,那么我们可以通过 devServer 提供的 before 钩子函数获取到内置的服务器对象进行处理请求,这个内置的服务器对象就是 webpack 的 devServer 即 8080 端口的 server,因为是在同一个服务器中请求数据所以也不会出现跨域问题。

before(app) { // 此app即webpack的devServer app.get("/api/test", (req, res, next) => { res.json({name: "even"}); }) }

我们还可以不通过 webpack 提供的 devServer 来启动 webpack,而是使用自己服务器来启动 webapck。

const express = require("express"); const app = express(); const webpack = require("webpack"); // 引入webpack const config = require("./webpack.config.js"); // 引入配置文件 const compiler = webpack(config); // 创建webpack的编译器 const middleWare = require("webpack-dev-middleware"); //引入webpack的中间件 app.use(middleWare(compiler)); // 将compiler编译器交给中间件处理 app.get("/api/test", (req, res, next) => { res.json({name: "lhb"}); }); app.listen(3000);

通过自定义服务器启动 webpack,这样 webpack 中的前端代码请求数据就和服务器的资源在同一个域中了。

六、resolve 配置

resolve 用于配置模块的解析相关参数的,其属性值为一个对象。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wzzxxp.html