32

Webpack(三):使用 plugin 以及本地服务器搭建

 4 years ago
source link: https://www.tuicool.com/articles/QbuyUzz
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

%E4%BD%BF%E7%94%A8%20plugin%20%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-0.png

使用 Plugin

banner-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 [email protected] --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 ,会报错:

%E4%BD%BF%E7%94%A8%20plugin%20%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-1.png

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

(1)

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

%E4%BD%BF%E7%94%A8%20plugin%20%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-2-1.jpg

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

%E4%BD%BF%E7%94%A8%20plugin%20%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-3.png

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

%E4%BD%BF%E7%94%A8%20plugin%20%E4%BB%A5%E5%8F%8A%E6%9C%AC%E5%9C%B0%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA-4.png

注意看上图!!!路径是用 \ 而不是 / 。。。改用 \ 之后就正常了。当然,是看到这个贴子 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'
  },

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK