什么是Webpack
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
为什么要使用WebPack
1、模块化,让我们可以把复杂的程序细化为小的文件;
2、类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能转换为JavaScript文件使浏览器可以识别;
3、Scss,less等CSS预处理器
4、...
这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。
那么,本文就给出webpack基本的一些配置(如何安装webpack及其使用前的准备工作网上已经给的够多,这里不做描述)。
webpack.config.js
配置如下:
const path = require(\'path\')
const config = require(\'./config\')
const VueLoaderPlugin = require(\'vue-loader/lib/plugin\');
const HtmlWebpackPlugin = require("html-webpack-plugin")
const CleanWebpackPlugin = require(\'clean-webpack-plugin\')
// const OpenBrowserPlugin = require(\'open-browser-webpack4-plugin\'); //没什么卵用
const webpack = require(\'webpack\')
function resolve (dir) {
return path.join(__dirname, \'..\', dir) //用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是/,Windows系统是\。
}
module.exports = {
// devtool: \'config.dev.devtool\', //每个module会通过eval()来执行,转化为字符串,并且生成一个DataUrl形式的SourceMap(#sourceMappingURL(base64)和#sourceURL)。
mode: \'development\', //设置此项是为了在运行npm start时告知webpack当前是处于开发环境下就不会有警告提示。因为开发环境下,生成的文件有点过大所以会有警告提示
//入口文件的配置项 __dirname是nodejs里的一个全局变量,它指向的是我们项目的根目录
entry: __dirname + \'/src/main.js\', //配置入口文件的地址,可以是单一入口,也可以是多入口。
//出口文件的配置项
output:{
path: __dirname + \'/dist\',//打包后输出目录
// filename:\'js/bundle-[chunkhash].js\', //打包后输出的文件 热更新(HMR)不能和[chunkhash]同时使用。
filename: \'js/bundle-[hash].js\'
}, //配置出口文件的地址,在webpack2.X版本后,支持多出口配置。
//模块:例如解读CSS,图片如何转换,压缩
module: { //配置模块,主要是解析CSS和图片转换压缩等功能。
rules: [
{
test: /\.vue$/,
loader: \'vue-loader\',
exclude: /node_modules/,
include: resolve(\'src\'),
options: {
compilerOptions: { //编译选项
preserveWhitespace: false //去掉元素之间的空格
}
}
},
{
test: /\.js$/,
loader: \'babel-loader\',
include: [resolve(\'src\')]
},
{
test: /\.html$/,
loader: \'html-loader\'
},
{
test: /\.css$/,
use: [\'style-loader\', \'css-loader\', \'postcss-loader\'], //这种写法也是可以的 webpack的执行顺序是从右往左,即先执行postcss-loader再执行css-loader,最后执行style-loader。
// loader: \'style-loader!css-loader!postcss-loader\' //这种写法也是可以的
/* 用以下这种写法来解决自动添加css前缀的问题也是可以的,
* 用了这种写法,上边的use: [\'style-loader\', \'css-loader\', \'postcss-loader\']或loader: \'style-loader!css-loader!postcss-loader\'就可以注释掉了,
* 这种写法不需要在根目录再创建一个postcss.config.js配置文件,
* 但这种写法由于不需要在根目录再创建一个postcss.config.js配置文件,
* 所以会导致在编译less或sass等文件时会报“No PostCSS Config found in”的错误,
* 就是因为少了一个postcss.config.js配置文件
*/
// use: [
// \'style-loader\',
// {
// loader: \'css-loader\',
// options: {importLoaders: 1}
// },
// {
// loader: \'postcss-loader\',
// options: {
// ident: \'postcss\',
// plugins: [
// require(\'autoprefixer\')({browsers: [\'last 5 versions\']}), //处理CSS前缀问题,自动添加前缀
// ]
// }
// }
// ],
},
{
test: /\.less$/,
use: [\'style-loader\', \'css-loader\', \'postcss-loader\', \'less-loader\'] //需要安装less
},
{
test: /\.scss$/,
use: [\'style-loader\', \'css-loader\', \'postcss-loader\', \'sass-loader\'] //需要安装node-sass,不需要安装sass
},
{
test: /\.(eot?.+|svg?.+|ttf?.+|otf?.+|woff?.+|woff2?.+)$/,
use: \'file-loader?name=assets/[name]-[hash:7].[ext]\'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/i,
loader: \'url-loader\',
/* 设置了limit后,文件体积大于limit的,
* 将直接被放在dist目录下的assets文件中(此时文件没有被压缩),
* 并加上hash值显示在页面中,如果小于limit的,
* 则直接被打包成base64形式的文件。
*/
options:{
limit: 10000,
name: \'assets/[name]-[hash:7].[ext]\'
}
},
]
},
resolve: {
extensions: [\'.js\', \'.vue\'],
modules: [
\'./\',
path.resolve(__dirname, \'node_modules\'),
]
},
//插件,用于生产模版和各项功能
plugins:[ //配置插件,根据你的需要配置不同功能的插件。
//添加了hash之后,会导致改变文件内容后重新打包时,文件名不同而内容越来越多,因此就要用到这个很好用的插件clean-webpack-plugin。
//clean-webpack-plugin每次都会清理dist文件夹的内容。通常,在每次构建前清理/dist文件夹,是比较推荐的做法,因此只会生成用到的文件。
new CleanWebpackPlugin([\'dist\']), //打包时有用 当运行npm start处在开发环境时,dist文件就会被删掉。
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
//filename: "index-[hash].html",
//filename: "default.html", //filename可以改变生成的html文件的名称,最好跟template是一样的名称,不然生成一个新的html文件,就要挨个去修改超链接地址了,也可以不设置filename。
template: "index.html",
//inject: true, //设置插件放置的位置,不设置的话默认为true就放置在</body>之前,参数有"head"、"body"、true、false,其中参数"body"和true的效果是一样的。
minify:{ //压缩html
removeComments: true, //删除注释
collapseWhitespace: true //删除空格
}
}),
// new OpenBrowserPlugin({ url: \'http://localhost:3000\' }), //自动在浏览器中运行,没什么卵用。webpack-dev-server自带的就有自动打开浏览器
new webpack.HotModuleReplacementPlugin()
],
//配置webpack开发服务功能
devServer:{
// hot: true, //这里如果设置为true就不会热重载了
// inline: true, //设置为true,当文件改变时会自动刷新页面。如果这里配置了inline为true,则上边的hot就不需要设置了(hot设置为true反而不会热重载),同时package.json中也不需要--inline了,且package.json不支持注释
open: config.dev.autoOpenBrowser, //用来自动打开浏览器
// publicPath: "config.dev.assetsPublicPath",
// proxy: config.dev.proxyTable, //设置反向代理
host: config.dev.host, //设置服务器的主机号
port: config.dev.port, //port配置属性指定了开启服务的端口号,如果省略,默认为"8080"
// overlay: true, //这个配置属性用来在编译出错的时候,在浏览器页面上显示错误,默认是false,可设置为true
// errorOverlay: true, //浏览器错误提示遮罩层
// notifyOnErrors: true, // 编译错误的时候通知提示,需要插件friendly-errors-webpack-plugin的配合
// quiet: true, //当它被设置为true的时候,控制台只输出第一次编译的信息,当你保存后再次编译的时候不会输出任何内容,包括错误和警告
// compress: true, //当它被设置为true的时候对所有的服务器资源采用gzip压缩
// historyApiFallback: true //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
}
};
//执行webpack命令会输出真实的文件,比如dist文件夹下的bundle-52b79b0580107adc0418.js,而执行webpack-dev-server命令输出的文件只存在于内存中,不输出真实的文件!
postcss.config.js
配置如下:
module.exports = {
plugins: [
require(\'autoprefixer\')({browsers: [\'last 5 versions\']})
]
}
webpack-dev-server
依赖的基本配置config/index.js
如下:
module.exports = {
dev: {
assetsPublicPath: \'/\', // 相对文件路径
proxyTable: {},
host: \'localhost\',
port: \'3000\',
autoOpenBrowser: true, // 是否自动打开浏览器
devtool: \'eval-source-map\', // Source Maps
}
}
项目依赖的插件package.json
基本配置如下:
{
"name": "webpackproject",
"version": "1.0.0",
"description": "webpacksimpleproject",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --inline",
"dev": "webpack --mode development",
"build": "webpack --mode production"
},
"dependencies": {
"webpack": "^4.2.0"
},
"devDependencies": {
"autoprefixer": "^8.2.0",
"babel-core": "^6.26.0",
"babel-loader": "^8.0.0-beta.2",
"babel-preset-env": "^2.0.0-beta.2",
"copy-webpack-plugin": "^4.5.1",
"css-loader": "^0.28.11",
"file-loader": "^1.1.11",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.1.0",
"image-webpack-loader": "^4.2.0",
"imagemin-webpack-plugin": "^2.1.0",
"less": "^3.0.1",
"less-loader": "^4.1.0",
"node-sass": "^4.8.3",
"postcss-loader": "^2.1.3",
"sass": "^1.0.0-rc.1",
"sass-loader": "^6.0.7",
"style-loader": "^0.20.3",
"url-loader": "^1.0.1",
"webpack-cli": "^3.3.2",
"vue-loader": "^15.2.4",
"webpack-dev-server": "^3.1.4",
"clean-webpack-plugin": "^0.1.19",
"open-browser-webpack4-plugin": "1.0.0"
},
"author": "tnnyang",
"license": "ISC"
}
以上就是webpack的基本配置,里边的注释详细介绍了各配置的功能。当运行npm start
后,DEMO项目会自动在浏览器中打开并可实现热重载。
以下写于2019年4月3日:
可能使用vue-loader v15版本后会提示报错,是因为15.*之后的版本在使用vue-loader时都需要伴随VueLoaderPlugin的。所以要么降低vue-loader的版本,要么如下设置:
// 加入到 plugins 里面就可以了
const VueLoaderPlugin = require(\'vue-loader/lib/plugin\');
plugins: [
new VueLoaderPlugin()
]