使用 Plugin

webpack 自带 BannerPlugin,我们只需要在 webpack.config.js 中配置即可:

const webpack = require('webpack'); //引入

module.exports = {
    entry:...,
    output:{...},
    module:{...},
    resolve:{...},
    plugins:[
        new webpack.BannerPlugin('Created by xxx');
    ]
}

html-webpack-plugin

之前我们的 index.html 都是在项目的根目录下的,这个文件最后也要打包到 dist 文件夹中。

HtmlWebpackPlugin 可以自动生成一个 已经引入bundle.jsindex.htmldist 文件夹中。

npm install html-webpack-plugin --save -dev

不过这个生成的文件默认是没有模板的(只有引入的 js),所以我们要配置一下:

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 引入

module.exports = {
    entry:...,
    output:{...},
    modules:{...},
    resolve:{...},
    plugins:[
        new ....,
        new HtmlWebpackPlugin({
            template:'./index.html'
        })
    ]
}

这之后,webpack 将会去 webpack.config.js 所在的文件夹寻找 index.html文件(最初的入口文件),并将其 html 结构作为新 index.html 的模板。也就是说,最初的入口文件仅提供一个模板。

Note

另外还要注意,前面我们说过,webpack 认为 index.html 位于 dist 中,所以导致了路径出错,我们是通过配置 output.publicPath 或者 url-loader.options.publicPath 来修正这个问题的。但是现在 index.html 确实位于 dist 中了,所以我们也可以把这两个配置改回来了。

uglifyjs-webpack-plugin

压缩 js 文件:

npm install uglifyjs-webpack-plugin@1 --save -dev

进行配置:

const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); //引入

module.exports = {
    entry:...,
    output:{...},
    modules:{...},
    resolve:{...},
    plugins:[
        new ....,
        new ....,
        new UglifyWebpackPlugin()
    ]
}

这里又因为版本不匹配的问题报错了,原因是 webpack@3 对应的 plugin 版本是 @1,所以如果 npm 安装的时候不指定版本,默认会安装最新的 @2 版本,后面打包就会报错了。

Webapck 搭建本地服务器

安装

Webpack 提供了一个可选的本地开发服务器,基于 node.js 搭建,内部使用 express 框架,可以实现热更新。

文件暂缓到内存中,内存中读取速度要比磁盘快很多,之后执行打包命令的时候才输出到磁盘。

首先安装一下:

npm install webpack-dev-server@2.9.3 --save -dev

Note:这里也要注意和 webpack 的版本对应。

之后配置一下:

module.exports = {
    entry:...,
    output:{...},
    modules:{...},
    resolve:{...},
    plugins:[...],
    devServer:{
   		contentBase:'./dist' // 为哪个文件夹提供本地服务
        inline: true,    // 开启热更新
        port:  8080           // 默认8080端口号
        open:true            // 开启服务器后自动打开浏览器
        historyApiFallback:...    // 在 SPA 页面中依赖 HTML5 的 history 模式     
    }
}

处理报错

这时候直接运行 webpack-dev-server ,会报错:

这里的操作,其实是试图在项目根目录下执行 webpack-dev-server.cmd,但当前目录并没有这个这个东西,所以报错了。这时候可能会有如下思路:

(1)

首先,webpack-dev-server.cmd 其实就位于 node_modules/.bin 文件夹中,我可以选择直接执行 node_modules/.bin/webpack-dev-server 或者是 cd 进目录后执行,如下图:

这个思路应该是没问题的,但是我实际这么做的时候报错了:

经过苦苦思索。。。好吧,犯了一个很傻逼的错误:

注意看上图!!!路径是用 \ 而不是/。。。改用 \之后就正常了。当然,是看到这个贴子 https://www.cnblogs.com/mqfblog/p/6444753.html 突然想到的。

(2)

第二个方法,全局安装 webpack-dev-server。这个当然没问题了,这样的话我不管在哪个路径下运行指令,这个指令总能被找到。但是这个方法不推荐,因为有版本冲突问题

(3)

第三个方法就是来到 package.json配置一下命令:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "dev":"webpack-dev-server"
},

这之后执行 npm run dev ,那么 npm script 的底层其实会做一些相应处理,自动到 node_modules/.bin 文件夹下寻找对应的 cmd 并执行。

更新缓慢

开启本地服务器,修改代码之后会发现可以自动刷新了。不过。。。

我进行到这一步的时候发现刷新大概需要 4 到 5 秒,对比使用 live server 时那种即时刷新的感觉,完全不是一个量级的好吗!然后把前面安装的 uglifyjs-webpack-plugin 去掉就正常了,看来是被这个插件影响到了。

这里也可以发现,实际上我们是在开发完成后才需要用到这个插件去压缩代码;相反地,webpack-dev-server则是在开发过程中要用到,也就是说,这两个东西的使用情境是不同的。那么,有没有方法可以依照使用情境把它们进行分离呢?

配置分离

  • 抽取公共配置
  • 分离开发环境配置和生产环境配置

在我们前面安装的 plugin 里,webpack-dev-server 只有开发的时候用得到,uglifyjs-webpack-plugin只有开发后用得到,其他的则是开发/生产时都要用到的,据此,我们可以在根目录新建 build 文件夹,并将这些配置分别写进三种类型的文件里:

dev.config.js / prod.config.js / base.config.js

形式上分离后,我们管理起来就方便了,之后借助插件进行配置的合并:

npm install webpack-merge --save -dev

dev.config.js:

const webpackMerge = require('webpackMerge');
const baseConfig = require('./base.config.js');
module.exports = webpackMerge(baseConfig,{
  devServer:{
    contentBase:'./dist',
    inline:true,
    open:true
  }
})

prod.config.js:

const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
const webpackMerge = require('webpack-merge');
const baseConfig = require('./base.config.js');

module.exports = webpackMerge(baseConfig,{
  plugins:[
    new UglifyjsWebpackPlugin()
  ]
})

base.config.js:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:...,
    output:{...},
    module:{...},
   	resolve:{...},
    plugins:[...]
}

这之后我们要解决两个问题:

首先,现在的 config 文件已经分离了,所以原先的 webpack.config.js可以删掉了,这里会发现删掉之后,原先配置的 npm script 指令失效了,所以来到 package.json配置一下:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack   --config ./build/base.config.js",
    "dev": "webpack-dev-server  --config ./build/base.config.js"
  },

加上 --config ./build/base.config.js,也就是现在以 base.config.js 这个配置文件为准。

第二个问题,如果我们直接打包,会发现在 build 下输出了 dist 文件夹,这是因为我们之前是这样配置 output.path 的:

output:{
    path:path.resolve(__dirname,'dist'),
    filename:'bundle.js'
  },

之前, __dirname 指向 webpack.config.js所在的目录,即根目录,后面跟着 dist,意思是打包到根目录下的 dist 文件夹。而现在,__dirname 指向的是 base.config.js所在的目录,即 build 文件夹,后面跟着 dist,意思是打包到 build下的 dist 文件夹。

所以要修正一下路径,改为 :

output:{
    path:path.resolve(__dirname,'../dist'),
    filename:'bundle.js'
  },

之后就可以正常打包了。当然,对于小型项目的话,一个配置文件也完全足够了。

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=188s4s5t1gb7g