随着前端体积越来越大, 功能越来越丰富, 这时候就需要将前端工程化, 而 webpack 就是用于将前端各种文件打包起来. 一个简单的 webpack 应该包含以下几个概念
入口起点
输出
配置
组件
加载器
插件
模块
模块热替换
适用情况
首先说明, 此情况不具备普遍性. 若你的情况与笔者类似那么希望这篇文章能够帮到你.
我的项目情况是这样的: 用 node.JS 做后台, ejs 做模板引擎 (即整个页面是一个 ejs 文件) 由 node.JS 将数据渲染完成后, 再将完整页面返回给用户.
那么这样做会遇到的问题:
1. 本项目没有 html 页面, ejs 的作用也不是引入公共的组件, 直接就是一个完整的页面, 用 webpack 中处理 ejs 文件的 loader 返回的是一个函数, 故会产生问题
2. 由于 node.JS 配置了静态资源目录 public, 而视图目录与之同级, webpack 在处理图像等静态资源目录的路径的时候会产生问题
3. 如果使用 publicpath 那么 Node.JS 在运行的时候就会找不到资源, 因为设置了静态资源的目录
如果你也遇到了类似的问题, 希望你能在本文中找到解决方法.
这里多说一句: 不要觉得我的项目很奇怪, 因为我当时写的时候, 知识储备不足, 等到后面发现不妥的时候, 为时已晚.
改起来太麻烦, 所以将错就错了......
解决方案
1. 处理 ejs
我在各个论坛, 官网搜寻良久, 始终没能找到, 能处理我这种情况的 loader.
没有办法之下, 只能换一个思路, 将 ejs 文件先转为 HTML
首先要修改文件, 那么就要修改服务器的模板引擎(这里是我的 App.JS)
那么要修改成什么呢? 我要让 Node.JS 使用 ejs 模板引擎, 但是使用 HTML 文件来渲染
这里我们要用的是 express 中的 App.engine 来注册一个引擎
代码如下:
- App.set('views',path.join(__dirname,'views'));// 设置模板引擎的目录
- App.engine('HTML', require('ejs').renderFile);
- App.set('view engine','HTML');
这样我们就可以将原本 views 视图目录中的 ejs 文件的后缀修改为. HTML 了
2.webpack 处理 HTML 文件
首先引入我眼帘的是 webpack 插件: HtmlWebpackPlugin
我找了许多文章, 文章中对 HTML 文件的处理无一列外都用到了这个插件
既然那么多人用, 那么它的强大是毋庸置疑的.
但是配置好后运行 webpack, 报了一个 locals 未定义的错误
报错代码:
由于 locals 是由 express 中的 res.render()传回页面的数据, 而在此时 webpack 处理的时候, 理所当然的会报未定义的错误了.
那么这个问题怎么解决呢?
我现在需要让 webpack 帮我处理 HTML 中的资源, 又要让 webpack 不要理会 ejs 的语法, 帮我继续压缩代码, 就陷入了一个十分难受的境地.
在搜寻良久无果后, 一篇误打误撞的文章启发了我
这篇文章的博主是希望, webpack 能够把 ejs 引入的模板打包到一个页面中, 而我恰恰相反, 我就是需要 webpack 不理会我的 ejs 代码.
于是解决办法氤氲而生.
首先我将原本 HTML 中的 JS 代码抽离到 test.JS 中
然后以这个 JS 文件为入口文件, 再以原本的 HTML 文件为模板
用 HtmlWebpackPlugin 来生成我所需要的压缩过后的 HTML
解决代码
- webpack.config.JS
- 'use strict';
- const path = require('path');
- const HtmlWebpackPlugin = require('HTML-webpack-plugin');
- // 打包 ejs
- module.exports = {
- entry: {
- test: './test.JS',// 入口文件 即一般来说 App.JS
- },
- mode:"production",// 生产环境
- output: {
- path: path.resolve(__dirname,'build'),// 输出路径
- filename: 'JS/[name]/[name].JS'// 输出后的文件名
- },
- externals: {
- jQuery:'Windows.jQuery'
- },// 外部加载的资源 这些都是不需要进行打包的
- module: {
- rules: [// 设置处理 JS 文件的 loader
- {test:/\.JS$/,use:'babel-loader',exclude:/node_modules/},
- {test:/\.CSS$/,use:["style-loader","CSS-loader"]},
- {
- test: /\.(PNG|jpg|gif)$/,
- use: [
- {
- loader: 'file-loader',
- options: {
- name: 'images/[name].[ext]'
- }
- }
- ]
- },
- {
- test: /\.(HTML)$/,
- use: {
- loader: 'HTML-loader',
- options: {
- attrs: [':data-src']
- }
- }
- }
- ]
- },
- plugins:[
- new HtmlWebpackPlugin({
- name:'test',
- template:'./public/init.HTML',// 模板文件
- filename:'views/test.HTML',// 目标文件
- minify:{
- collapseWhitespace:true,
- collapseInlineTagWhitespace:true,
- conservativeCollapse:true,
- minifyCSS:true,
- minifyJS: true,
- removeComments:true,
- trimCustomFragments:true
- }
- })
- ],
- optimization: {
- minimize: true// 是否压缩代码
- }
- };
上面的 minify 参数主要是配置 HTML 压缩的
入口文件 test.JS
这里面没有任何有关 webpack 的代码, 全是项目的业务代码, 故在这里就不粘了
运行 webpack 大功告成
我们来看看打包前后的 HTML
打包前:
打包后
大小对比
启动 Node.JS 服务器
问题解决 睡觉咯~~
来源: http://www.jb51.net/article/147656.htm