一、一个常见的webpack配置文件
// 一个常见的webpack配置文件
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: __dirname + "/app/main.js", //已多次提及的唯一入口文件
output: {
path: __dirname + "/build",
filename: "bundle-[hash].js"
},
devtool: 'none',
devServer: {
contentBase: "./public", //本地服务器所加载的页面所在的目录
historyApiFallback: true, //不跳转
inline: true,
hot: true
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: "babel-loader"
},
exclude: /node_modules/
}, {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [{
loader: "css-loader",
options: {
modules: true,
localIdentName: '[name]__[local]--[hash:base64:5]'
}
}, {
loader: "postcss-loader"
}],
})
}
}
]
},
plugins: [
new webpack.BannerPlugin('版权所有,翻版必究'),
new HtmlWebpackPlugin({
template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin(),
new ExtractTextPlugin("style.css")
]
};
二、loader和plugin的区别
loader
loader相当于一个转换器,操作的是文件,可以将A文件进行编译形成B文件,例如将A.scss或A.less转变成B.css,是单纯的文件转换过程;
Loader是webpack最重要的功能之一,Loader能够让webpack处理不同的文件,它可以将所有类型的文件转换成webpack能够处理的有效模块,然后利用webpack的打包能力,对他们进行处理,即将所有类型的文件转换成应用程序的依赖图可以直接引用的模块;
1)loader可以将sass,less文件的写法转换成css,而不再使用其他转换工具;
2)loader可以将ES6或ES7的代码转换成大多数浏览器兼容的JS代码;
3)loader可以将React中的JSX转换成JavaScript代码;
webpack中的Loader有两个目标:
1)识别出应该被对应的loader进行转换的文件(使用test属性);
2)转换这些文件,从而使其能够被添加到依赖图中(并最终添加到bundle中)(使用use属性);
用法:Loader需要单独安装,需要什么Loader就使用npm安装即可,并对应webpack.config.js中的module属性:
module:{
rules: [{
test: // 用于匹配处理文件的扩展名的表达式,必须
use: // loader名称,就是要使用的模块名,必须
include/exclude: // 手动添加必须处理的文件(夹)或屏蔽不需要处理的文件(夹),可选
query: // 为loader提供额外的设置选项,可选
}]
}
// use有三种写法:
// 方法一:直接用use:
use:['style-loader','css-loader']
// 方法二:将use换成loader:
loader:['style-loader','css-loader']
// 方法三:使用use + loader:
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.css$/,
use: [{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
}]
}]
}
plugin
plugin相当于一个扩展器,它丰富了webpack本身,针对loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务;
loader被用于转换某些类型的模块,而plugin则可以用于执行广泛的任务,插件的范围包括从打包优化和压缩,一直到重新定义环境中的变量,插件接口功能极其强大,可以用来处理各种各样的任务,plugin通过对节点的监听,从而找到合适的节点对文件做适当的处理;
run:开始编译
make:从entry开始递归分析依赖并对依赖进行build
build-moodule:使用loader加载文件并build模块
normal-module-loader:对loader加载的文件用acorn编译,生成抽象语法树AST
program:开始对AST进行遍历,当遇到require时触发call
require:事件
seal:所有依赖build完成,开始对chunk进行优化(抽取公共模块、加hash等)
optimize-chunk-assets:压缩代码
emit:把各个chunk输出到结果文件
想要使用一个插件,只需要require它,然后将它添加到plugins数组中,多数插件可以通过选项自定义,也可以在一个配置中因为不同目的而多次使用同一个插件,这时需要通过使用new操作符来创建它的一个实例;webpack插件是一个具有apply属性的JavaScript对象,apply属性会被webpack compiler调用,并且compiler对象可在整个编译周期访问;由于插件可以携带参数/选项,必须在webpack配置中,向plugins属性传入new实例;
// webpack.config.js文件头部引入插件
const uglify = require('uglifyjs-webpack-plugin');
const htmlPlugin= require('html-webpack-plugin');
// 插件配置
plugins:[
new uglify(),
new htmlPlugin({
minify:{
removeAttributeQuotes: true
},
hash: true,
template: './src/index.html'
}),
],
(1)JS 压缩:webpack中JS压缩使用的是 uglifyjs-webpack-plugin插件;
const uglify = require('uglifyjs-webpack-plugin');
plugins: [
new uglify();
]
注意:在开发环境中使用该插件会报错,因为在开发预览时需要明确报错行数和错误信息,所以不需要对JS压缩,而生产环境中才会对JS压缩,devServer用于开发环境,而压缩JS用于生产环境,在开发中做生产环境的事情,所以会报错;
(2)打包HTML:要将 HTML 文件从 src 目录下打包到 dist 目录下,需要借助 html-webpack-plugin 插件,该插件需要安装;
npm install html-webpack-plugin --save-dev
// 配置:
const htmlPlugin = require('html-webpack-plugin');
plugins: [
new htmlPlugin({
minify: { // 对HTML文件进行压缩
removeAttributeQuotes: true // 去除属性的双引号
},
hash: true, // 为了避免缓存js,加入 hash
template: './src/index.html' // 要打包的HTML模板路径和文件名称
})
]
三、webpack-dev-server和http服务器如nginx有什么区别?
webpack-dev-server 的原理:正向代理隐藏了真实的客户端,而反向代理隐藏了真实的服务器,webpack-dev-server 扮演了一个代理服务器的角色,由于服务器之间通信不会存在前端常见的同源策略,这样当请求 webpack-dev-server 时,它会从真实的服务器中请求数据,然后将数据发送给浏览器;
webpack-dev-server 主要是启动了一个使用express的Http服务器,启动webpack-dev-server后,你在目标文件夹中是看不到编译后的文件的,实时编译后的文件都保存到了内存当中,因此使用webpack-dev-server进行开发的时候看不到编译后的文件;
webpack-dev-server 使用内存来存储webpack开发环境下的打包文件,并且可以使用模块热更新,他比传统的http服务对开发更加简单高效;
var server = new WebpackDevServer(compiler, {
contentBase: "/path/to/directory",
//content-base 配置
hot: true,
//开启 HMR,由 webpack-dev-server 发送 "webpackHotUpdate" 消息到客户端代码
historyApiFallback: false,
//单页应用 404 转向 index.html
compress: true,
//开启资源的 gzip 压缩
proxy: {
"**": "http://localhost:9090"
},
//代理配置,来源于 http-proxy-middleware
setup: function(app) {
//webpack-dev-server 本身是 Express 服务器可以添加自己的路由
// app.get('/some/path', function(req, res) {
// res.json({ custom: 'response' });
// });
},
//为 Express 服务器的 express.static 方法配置参数 http://expressjs.com/en/4x/api.html#express.static
staticOptions: {
},
//在 inline 模式下用于控制在浏览器中打印的 log 级别,如`error`, `warning`, `info` or `none`.
clientLogLevel: "info",
//不在控制台打印任何 log
quiet: false,
//不输出启动 log
noInfo: false,
//webpack 不监听文件的变化,每次请求来的时候重新编译
lazy: true,
//文件名称
filename: "bundle.js",
//webpack 的 watch 配置,每隔多少秒检查文件的变化
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
//output.path 的虚拟路径映射
publicPath: "/assets/",
//设置自定义 http 头
headers: { "X-Custom-Header": "yes" },
//打包状态信息输出配置
stats: { colors: true },
//配置 https 需要的证书等
https: {
cert: fs.readFileSync("path-to-cert-file.pem"),
key: fs.readFileSync("path-to-key-file.pem"),
cacert: fs.readFileSync("path-to-cacert-file.pem")
}
});
server.listen(8080, "localhost", function() {});
// server.close();
bundle是由webpack打包出来的文件,chunk是指webpack在进行模块的依赖分析的时候,代码分割出来的代码块;module是开发中的单个模块;
Tree-shaking是指在打包中去除那些引入了,但是在代码中没有被用到的那些死代码,在webpack中Tree-shaking是通过uglifySPlugin来Tree-shaking JS,Css需要使用Purify-CSS;
参考链接:
入门webpack,看这篇就够了
webpack3-loader和plugin的概念理解
webpack-dev-server 核心概念
网友评论