深入学习webpack
webpack配置是标准的Node.js CommonJS模块,webpack中的绝对路径指"/src/css/file",相对路径指"../css/file"。
温馨提示:本篇文章立足于3.5.x版本。
一、入口,entry
entry值可以是字符串,数组,对象。
//写法1是写法2的简写
const config = {
entry: './src/file1.js'
};
//写法2
const config = {
entry: {
main: './src/file1.js'
}
};
const config = {
entry: ['./src/file1.js','./src/file2.js']
};
const config = {
entry: {
main: './src/file1.js',
app: './src/file2.js'
}
};
二、输出,output
const config = {
output: {
filename: 'bundle.js',
path: '/dist'
}
};
webpack有多种占位符,常见的如下:
[name]:代表打包后文件的名称,在entry或代码中确定;
[id]:webpack给块分配的内部chunk id,如果你没有隐藏,可以在打包后的命令行中看到;
[hash]:每次构建过程中,生成的唯一hash值;
[chunkhash]:依据于打包生成文件内容的hash值,内容不变,值不变。
三、模块,Modules
webpack模块有以下几种方式表达依赖关系:
1、ES2015 import;
2、同步,CommonJS require;
3、异步,AMD define和require语句;
4、css/less/sass中的@import;
5、样式中的url(...)和html文件中的<img src="..."/>。
loader是运行在Node.js中的函数,可以将资源文件作为参数,返回新的资源文件。loader用于加载某些资源文件,因为webpack本身只能打包CommonJS规范的js文件,对于其他资源,例如css,图片等,是没有办法加载的,这就需要对应的loader将资源转换。
1、babel-loader
加载ES2015+代码,然后使用Babel转译为ES5。
// npm一次性安装多个依赖模块,模块之间用空格隔开 npm install --save-dev babel-core babel-loader babel-preset-es2015
npm install --save-dev babel-loader babel-core babel-preset-env webpack
//单独配置.babelrc文件
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
plugins: [require('babel-plugin-transform-object-rest-spread')]
}
}
}
]
}
2、css-loader
解析css文件后,使用import加载,并且返回css代码。
npm install --save-dev css-loader
import css from 'file.css';
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
3、style-loader
将模块的导出作为样式添加到DOM中。
npm install style-loader --save-dev
import style from './file.css';
module: {
rules: [
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}
]
}
4、sass-loader
加载sass文件。
#安装sass-loader npm i -D node-sass sass-loader css-loader
//webpack.config.js
module.exports={
module:{
rules:[
{
test:/\.scss$/,
use:[
"style-loader",
"css-loader",
"sass-loader"
]
}
]
}
}
//index.js,自动编译成css require "./main.scss"
5、postcss-loader
使用postcss加载和转译css/sss文件。
npm i -D postcss-loader
//postcss.config.js
module.exports = {
parser: 'sugarss',
plugins: {
'postcss-import': {},
'postcss-cssnext': {},
'autoprefixer': {},
'cssnano': {}
}
}
//webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
{ loader: 'css-loader', options: { importLoaders: 1 } },
'postcss-loader'
]
}
]
}
}
6、url-loader
像file loader一样工作,但如果文件小于限制,可以返回data URL。
npm install --save-dev url-loader
import img from './image.png';
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
7、file-loader
将文件发送到输出文件夹,并返回(相对)URL。
npm install --save-dev file-loader
import img from './file.png';
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[path][name].[ext]?[hash]'
}
}
]
}
]
}
8、html-loader
导出html为字符串,需要引用静态资源。
npm i -D html-loader
module: {
rules: [{
test: /\.html$/,
use: [ {
loader: 'html-loader',
options: {
minimize: true
}
}]
}]
}
五、插件,plugins
webpack插件是一个具有apply属性的JavaScript对象,apply属性会被webpackcompiler调用,并且compiler对象可在整个compilation生命周期访问。plugin用于扩展webpack的功能,直接作用于webpack。
1、内置插件
A、BannerPlugin
为每个chunk文件头部添加注释信息。
new webpack.BannerPlugin(str)
B、CommonsChunkPlugin
它从根本上允许我们从不同的bundle中提取所有的公共模块,并且将他们加入公共bundle中。如果公共bundle不存在,那么它将会创建一个出来。
如果有任意模块加载了两次或更多(通过minChunks设置该值),它就会被打包进一个叫commons.js的文件里,后面你就可以在客户端缓存这个文件了。当然,这肯定会造成一次额外的请求,但是却避免了客户端多次下载相同库的问题。这个带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件。
new webpack.optimize.CommonsChunkPlugin({
name: "manifest",
minChunks: Infinity
})
C、DefinePlugin
创建一个在编译时可配置的全局常量,如果你自定义了一个全局变量PRODUCTION,可在此设置其值来区分开发还是生产环境,是启动dev server或者是prod server。
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production') // or development
})
D、EnvironmentPlugin
实际上是DefinePlugin插件中对process.env进行设置的简写形式,如new webpack.EnvironmentPlugin(['NODE_ENV', 'DEBUG']) 将设置process.env.NODE_ENV='DEBUG'
E、UglifyJsPlugin
压缩JS代码。
const webpack = require('webpack');
module.exports = {
plugins:[
new webpack.optimize.UglifyJsPlugin({
sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0)
})
]
}
F、UglifyjsWebpackPlugin
npm i -D uglifyjs-webpack-plugin
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
new UglifyJSPlugin()
]
}
G、HotModuleReplacementPlugin
启用热替换模块(Hot Module Replacement),也被称为HMR,永远不要在生产环境(production)下启用HMR。
new webpack.HotModuleReplacementPlugin()
H、ProvidePlugin
自动加载模块,不要import或者require引入。
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
2、非内置插件
A、ExtractTextWebpackPlugin
代码拆分,分离css和js文件。它将所有的入口chunk中引用的 *.css,移动到独立分离的css文件,使得样式不再内嵌到jsbundle中,而是会放到一个单独的css文件(即styles.css)当中。如果你的样式文件大小较大,这会做更快提前加载,因为css bundle会跟js bundle并行加载。
npm install --save-dev extract-text-webpack-plugin
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css")
]
}
B、HtmlWebpackPlugin
这个插件的作用是依据一个简单的index.html模板,生成一个自动引用你打包后的JS文件的新index.html,在每次生成的js文件名称不同时非常有用(比如添加了hash值)。
npm install --save-dev html-webpack-plugin
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};module.exports = webpackConfig;
C、CompressionWebpackPlugin
使用配置的算法(如gzip)压缩打包生成的文件。
npm i -D compression-webpack-plugin
var CompressionPlugin = require("compression-webpack-plugin");
module.exports = {
plugins: [
new CompressionPlugin({
asset: "[path].gz[query]",
algorithm: "gzip",
test: /\.(js|html)$/,
threshold: 10240,
minRatio: 0.8
})
]
}
D、visualizer和stats
const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin;
const Visualizer = require('webpack-visualizer-plugin');
module.exports = {
...
plugins: [
new StatsWriterPlugin({
fields: null,
stats: {
chunkModules: true
}
}),
new Visualizer({
filename: './statistics.html'
}),
...
]
}
六、devtool
// 以牺牲构建速度为代价,但是map表最详细。 devtool: "source-map" // 嵌入到源文件中,为打包前的每一个文件添加sourcemap的DataUrl,DataUrl是包含一个文件完整souremap信息的Base64格式化后的字符串,而不是一个 url。 devtool: "inline-source-map" // 没有模块映射,而是命名模块,以牺牲细节达到最快。 devtool: "eval" // 将SourceMap嵌入到每个模块中 devtool: "eval-source-map" // SourceMap不在源文件中引用 devtool: "hidden-source-map" //没有模块映射 devtool: "cheap-source-map" //有模块映射 devtool: "cheap-module-source-map"
当webpack打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。JavaScript提供了source map功能,将编译后的代码映射回源代码,使调试更容易。如果一个错误来自于b.js,source map就会明确的告诉你。
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/main.js',
print: './src/sec.js'
},
+ devtool: 'inline-source-map',
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Development'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
假设在sec.js中写一个错误语法,编译打包后,刷新页面,就会在控制台看到错误文件及出错行数。
七、devServer
用于设置webpack-dev-server的命令行。
devServer: {
bonjour:true,
contentBase: path.join(__dirname, "dist"),
compress: true,
historyApiFallback: true,
hot: true,
inline: true,
open:true
}
看了那么多文档,一般都是清一色的英文,这次竟然发现devServer的属性值中有bonjour,哈哈,挺好的,我猜写webpack的开发人员会点法语。
//webpack.config.js
const path = require('path');
module.exports = {
entry:"",
output: {
path: path.resolve(__dirname, "dist"), //路径解析
filename: "bundle.js"
},
module: {
rules: []
},
plugins: [],
devtool: "inline-source-map",
devServer: {
contentBase: "./public", //本地服务器所加载的页面所在的目录
historyApiFallback: true, //不跳转
inline: true, //实时刷新
stats:{}
},
target:"web",
externals: {
vue: 'vue'
},
performance: {
hints: "error" //生产环境推荐用error,开发环境推荐用warning
}
}
深入学习webpack的更多相关文章
- [译]开始学习webpack
写在前面: 文章翻译自petehunt大神的petehunt/webpack-howto,作为学习webpack的开始.fork了一份,翻译后的在这里https://github.com/zjzhom ...
- 深入学习webpack(一)
深入学习webpack(一) 模块化的相关库和工具已经很多了,包括require.js.sea.js和一些工程化工具webpack.gulp.grant.那么我们该如何选择呢? 其实,我们只需要掌握了 ...
- webpack4 学习 --- webpack和webpack-dev-server
以前了解过webpack2, 所以对webpack 不是很陌生,就直接入主题吧.新建一个文件夹,就叫它webpack-tut吧.然后在文件中新建一个src 文件夹,存放我们的源文件,再在src 文件夹 ...
- 如何学习 Webpack
webpack-howto Tip: 本文是 webpack-howto 的原文,我觉得这篇文章写得非常好,确实算是目前学习 webpack 入门的必读文章.直接收录之. 本教程的目标 这是一本教你如 ...
- 深入学习webpack(二)
深入学习webpack(二) 在深入学习webpack(一)中,我通过一个例子介绍了webpack的基本使用方法,下面将更为系统的学习webpack的基本概念,对于一门技术的掌握我认为系统化还是很重要 ...
- 跟我一起学习webpack使用配置文件(二)
接着跟我一起学习webpack(一)中的项目来,我们接下来使用配置文件 使用npx webpack -h 我们可以查看webpack的配置参数 从我们在package.json中添加的命令来看,当项目 ...
- 学习webpack基础笔记01
学习webpack基础笔记 1.webpack搭建环境最重要的就是如何使用loader和plugins,使用yarn/npm安装插件.预处理器,正确的配置好去使用 2.从0配置webpack - 1. ...
- vue第二单元(webpack的配置-学习webpack的常用配置)
第二单元(webpack的配置-学习webpack的常用配置) #课程目标 掌握webpack的常用配置 掌握如何根据实际的需求修改webpack的对应配置 了解webpack-dev-server的 ...
- 零基础学习webpack打包管理
这些天在项目之余的时间学习了webpack打包项目的东西,非常荣幸的找到一些大神的文章来学习,死劲嚼了几天,终于略知一二.在以后的工作上还需继续学习,下面我将分享我这几天学到的一点东西,希望能让我一个 ...
- Webpack学习-Webpack初识
一.前言 webpack 到底是个什么东西呢,看了一大堆的文档,没一个能看懂的,因为上来就是给个module.exports 然后列一大堆配置,这个干啥,那个干啥,没一点用.但凡要用一个东西,一个东西 ...
随机推荐
- Spring+Struts+Mybatis+Shiro整合配置
Jar包
- Linux的记事本 Vi和Vim
⒈Vi和Vim的三种模式 ①正常模式 在正常模式下可以使用快捷键 默认进入的是正常模式 ②编辑模式(插入模式) 在该模式下可以输入内容 按下I,i,O,o,A,a,R,r等任何一个字母之后才可以进入该 ...
- Jade教程
Jade 是一个高性能的模板引擎,它深受 Haml 影响,它是用 JavaScript 实现的,并且可以供 Node 使用. 如何在jade模板上加业务逻辑 if res.length==5 h1= ...
- datatables 添加excel下载
Datatables 版本 1.10.12 和普通datatables不一样的是: 引入包 <script src="../../vendor/datatables/js/dataTa ...
- Pcap4J实现抓包器
前段时间搞抓包程序,打算使用Pcap4J实现,发现除了GitHub,其它资料少之又少,几乎都是不起作用. 被迫我一直看(日本作者!)英文注解的源码和sample和test,比较费劲+营养很少.因为几乎 ...
- Jenkins实现定时、顺序编译
1 Jenkins实现定时.顺序编译 l Jenkins 编译流程:更新代码,编译公共服务,编译普通服务(普通服务依赖于公共服务).以下图为例,首先执行 update,再执行 icto_c ...
- vuejs初学入门环境搭建
一.Nodejs: 1.安装下载:http://nodejs.cn/download/ 2.Node.js安装配置: http://www.runoob.com/nodejs/nodejs ...
- zabbix系列(六)zabbix添加对ubuntu系统的监控
在ubuntu os上安装agent,使用如下命令: wget http://mirrors.aliyun.com/zabbix/zabbix/3.0/ubuntu/pool/main/z/zabbi ...
- 在jsp页面,将小数转换为百分比
<fmt:formatNumber type="number" value="${temp.illegalCount*100/temp.unitCount}&quo ...
- 04-Bootstrap的插件
1.下拉菜单 代码如下: <div class="dropdown"> <button class="btn btn-default dropdown- ...