Webpack是一个模块打包器。这意味着,它的目的是(根据它们之间的依赖)合并一组模块。它的输出可能是一个或多个文件。除了打包模块,Webpack可以对你的文件做各种事情:例如,把SCSS转换为CSS,或者把Type转换为Java。它甚至可以压缩你所有的图像文件!但是,你究竟是为什么想要打包它们呢?
webpack的意思就是模块化打包
官网: [webpack](https://www.webpackjs.com/)
环境搭建
创建package.json文件
cmd命令行输入 npm init
根据提示输入package文件的信息
安装webpack
本地安装(可以为每个项目安装 不同版本,方便新项目)
npm install --save-dev webpack
npm install --save-dev webpack-cli
全局安装
npm install --global --save-dev webpack
打包
需要创建一个src文件夹
打包命令 (需要把这两个命令写入package.json的scripts里)
webpack --mode development 开发模式
webpack --mode production 生产模式
配置入口出口文件
新建webpack.config.js文件
导出对象:
const path = require('path')
module.exports = {
entry: './public/index.js', // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 文件打包后的存放路径 __dirname nodejs获取当前文件路径
filename: 'bundle.js' // 打包的文件名
}
}
此时创建个pbulic文件夹, 新建index.js,即可运行打包npm run dev/npm run build
多文件入口,单文件出口
const path = require('path')
module.exports = {
entry: ['./public/index.js', './public/home.js'] // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 文件打包后的存放路径 __dirname nodejs获取当前文件路径
filename: 'bundle.js' // 打包的文件名
}
}
多入口,多出口
const path = require('path')
module.exports = {
entry: {
pageOne: './public/index1.js',
pageTwo: './public/index2.js',
}, // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 文件打包后的存放路径 __dirname nodejs获取当前文件路径
filename: '[name].js' // 打包的文件名, name会取入口文件的key值
}
}
简洁化引入路径,可以通过配置resolve.alias 来简化引入路径
*在webpack.config.js里写入以下配置,即可*
resolve: {
alias: {
//指向当前路径,以后请求则变成设置的路径 例如: require('util') === require( __dirname + '/src/util')
node_modules: __dirname + '/node_modules',
util: __dirname + '/src/util',
lib: __dirname + '/src/lib',
component: __dirname + '/src/comp',
views: __dirname + '/src/views',
service: __dirname + '/src/service',
image: __dirname + '/src/image'
}
}
webpack-dev-server 配置和应用
安装webpack-dev-server
npm install --save-dev webpack-dev-server
配置webpack.config.js文件
【目前的自动刷新貌似只监听入口的js文件修改才会触发】
const path = require('path')
module.exports = {
entry: './public/index.js', // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 文件打包后的存放路径 __dirname nodejs获取当前文件路径
filename: 'bundle.js' // 打包的文件名
},
devServer: {
// contentBase: './build', // 设置服务器访问的基本目录,需要跟打包目录一致
// 必须设置为bundle.js 所在的目录,开发模式不设置,或设置未false
host: 'localhost', // 服务器的ip地址
port: 8080, // 服务器访问的端口
open: true, // 启动服务时候是否自动打开页面
inline: true, // 官方推荐
hot: true, // 启动热更新
watchOptions: [
aggregateTimeout: 2000, // 浏览器延迟多久更新
poll: 1000, // 每秒检查一次变动
],
proxy: {
'/api': {
target: 'http://api.twobyoung.com', //API服务器的地址
ws: true, //代理websockets
changeOrigin: true, // 是否跨域,虚拟的站点需要更管origin
pathRewrite: {
// '^/api5'是一个正则表达式,表示要匹配请求的url中,全部'http://localhost:8081/api5' 转接为 http://localhost:8081/api/
'^/api5': '/api',
//重写路径 比如'/api/aaa/ccc'重写为'/aaa/ccc'
'^/api': '',
}
},
'/foo': {
target: 'http://www.twobyoung.com'
}
}
}
}
打包自动生成html文件来使用打包后的文件
自动生成html依赖的项 是:
html-webpack-plugin
先安装
npm install --save-dev html-webpack-plugin
配置package.config.js文件
const htmlWebpackPlugin= require('html-webpack-plugin')
module.exports = {
plugins: [
new htmlWebpackPlugin({
template: './public/index.html', // 模板,根据此模板生成html; 可以是html ejs等,引入什么文件就需要安装什么loader
filename: 'webpack.html',
chunks: ['manifest ', 'vendor ', 'entry'],
// 打包完的html文件 需要引入的入口js文件,如果不设置会引入所有的js文件. 其中 vendor 是对node_modules 里公共模块的提取;mainfest 是vendor 的缓存
excludeChunks: ['test'], // 意思是排除哪些js文件需要引入
minify: { // 其他设置项,可以忽略使用默认值
minisize: true, // 是否打包为最小值
removeAttributeQuotes: true, // 是否去除引号
removeComments: true, // 是否去除注释
collapseWhiteSpace: true, // 是否去除空格
minifyCss: true, // 是否压缩html内的样式
minifyJs: true, // 是否压缩html内的js
removeEmptyElements: true, // 去除内容为空的元素
},
hash: true, // 引入产出的时候加 哈希,避免缓存
inject: true, // true, false ,body, head ,选择js文件注入的位置,true 和body 会放到body最后。head放到head里,false是不注入
favicon: './image/icon.ico', // 添加icon
})
]
}
package.json 里配置本地服务scripts
'scripts': {
'dev': 'webpack --mode development',
'build': 'webpack --mode production',
'start': 'webpack-dev-server --mode development'
}
webpack加载css 的loader
loader
因为webpack本身只识别js文件,但是开发过程中还需要很多css,img等类型文件。
所以就需要loader来进行转换
安装loader
npm install style-loader css-loader
配置loader
在webpack.config.js文件里写入
module: {
rules: [
{
test: /.css$/,
use: ['style-loader',
{loader: 'css-loader', options: { sourceMap: true }} // 如果要开启css的sourcemap可以这样设置
] // cssloader需要css 和 style 两个loader。style-loader必须放在前面
},
{ test: /.ts$/, use: 'ts-loader' }
]
}
**处理less和sass文件**(两种方式类似,这里只讲一种)
webpack可以将less和sass文件直接处理成css文件
需要依赖于less-loader 和sass-loader 两个loader
安装
【注意,要使用less-loader 需要安装less 和less-loader】
npm install --save-dev less-loader
npm install --save-dev less
配置
module: {
rules: [
{
test: /.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
}
]
}
webpack文件处理
图片处理(字体文件处理类似)
需要用到file-loader
npm install --save-dev file-loader
配置
module: {
rules: [
{
test: /.(png|jpg|jpeg|gif)$/,
use: 'file-loader'
}
]
}
file-loader也可以进行选项配置
module: {
rules: [
{
test: /.(png|jpg|jpeg|gif)$/,
use: [
'file-loader',
{
options: {
name: '[path][hash].[ext]', // 打包后文件的名字
// [path]资源相对于context的路径,加上之后会在build文件夹里创建path指向的文件夹
context: '../', // 生成文件所在文件夹的控制,比如加上../ 生成的图片会放在 [public上级文件夹名] + public 下
publicPath: 'http://www.twobyoung.com/health/123.jpg', // 打包后将引用的图片固定为这个网络图片
outputPath: './myImg' // 将图片放在自定义的文件夹名下
}
}
]
}
]
}
拷贝静态文件
需要用到copy-webpack-plugin
npm install --save-dev copy-webpack-plugin
const copyPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
new copyPlugin([ // **这里要注意,传入的参数一定是要数组**
{
from: __dirname + '/static', // 从哪拷贝
to: __dirname + '/build/static' // 拷贝到哪
}
])
]
}
删除上次打包的文件
主要用于清楚带哈希值名称的文件
需要用到 clean-webpack-plugin
npm install --save-dev clean-webpack-plugin
const cleanPlugin = require('clean-webpack-plugin')
module.exports = {
plugins: [
new cleanPlugin (['./build']) // **这里要注意,传入的参数一定是要数组**
]
}
第三方js库的引用
以jquery库为例
本地导入
编写配置文件
这里会用到webpack本身的一个插件 webpack.ProvidePlugin.
webpack.ProvidePlugin是一个键值对形式 。键就是我们项目中使用的变量名,值就是键所指向的库。webpack.ProvidePlugin会优先从npm安装的库里查找符合的库。
在 webpack.config.js里写入
const webpack = require('webpack') // 这里要注意引入webpack实例,否则无法访问providePlugin
resolve: {
alias: {
jQuery: path.resolve(__dirname, 'public/js/jquery.min.js')
}
}, // 指向库的路径
plugins: [
new webpack.ProvidePlugin({
jq: 'jQuery'
})
]
npm 安装库
npm install jquery --save-dev
使用
import $ from 'jquery'
使用babel-loader编译es6
babel转换语法需要依赖三个项:
babel-loader 负责es6语法转换
babel-core babel 核心包
babel-preset-env 告诉babel使用那种转码规则进行文件处理
**安装**
npm install babel-loader @babel/core @babel/preset-env --save-dev
loader进行配置
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/, // 这里需要对node_modules里现成的js文件进行排除,只编译自己写的js即可
use: 'babel-loader'
}
]
}
**转换规则配置**
在根目录新建一个 .babelrc文件
写入规则,例如:
{
'presets': ['@babel/preset-env']
}
也可以在loader的配置里写入转换规则
module: {
rules: [
{
test: /.js$/,
exclude: /node_modules/,
use: [
'babel-loader',
options: {
presets: ['@babel/preset-env']
}
]
}
]
}
提取css到单独的文件
ExtractTextPlugin 老版插件(webpack 4使用)
**安装**
npm install --save-dev extract-text-webpack-plugin@next
后边必须加@next要不然会报错
配置
在webpack.config.js里写入
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = {
rules: [
{
test: '/.css$/',
use: ExtractTextPlugin.extract({
fallback: 'style-loader', // 如何提取css文件
use: 'css-loader' // 告诉它如何编译css
})
}
],
plugins: [
new ExtractTextPlugin('./css/index.css') // 这里传入生成的css文件名
]
}
mini-css-extract-plugin 新版插件
**安装**
npm install --save-dev mini-css-extract-plugin
配置
在webpack.config.js里写入
const MiniCssPlugin = require('extract-text-webpack-plugin')
module.exports = {
rules: [
{
test: '/.css$/',
use: [MiniCssPlugin .loader, 'css-loader']
}
],
plugins: [
new MiniCssPlugin({
filename: './css/index.css'
}) // 这里传入生成的css文件名
]
}
### 压缩css文件
压缩css使用的插件是 optimize-css-assets-webpack-plugin
npm install --save-dev optimize-css-assets-webpack-plugin
*配置*
在webpack.config.js里写入
const optimizeCss = require('optimize-css-assets-webpack-plugin')
module.exports = {
rules: [
{
test: '/.css$/',
use: [MiniCssPlugin .loader, 'css-loader']
}
],
plugins: [
new optimizeCss ({
assetsNameRegExp: /.css$/g, // 正则表达式,用于匹配需要优化的压缩的资源名, 默认/.css$/g
cssProcessor: require('cssnano'), // 用于压缩和优化css的处理器 默认 是 cssnano
cssProcessorPluginOptions: {
preset: ['default', {discardComments: {removeAll: true}}]
},
// 传递给cssProcessor的插件选项,默认{}, discardComments: 去除注释
canPrint: true // 表示插件能否在console中log信息,默认true
})
]
}
### postCss处理浏览器前缀
需要应用postcss-loader 和autoprefixer
安装
npm install --save-dev postcss-loader autoprefixer
配置
module: {
rules: [
{
test: /.less$/,
use: ['style-loader', 'css-loader', 'less-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: [
'ie >= 8', // ie 版本大于等于8
'Firefox >= 20', // 火狐版本大于等于20
'Safari' >= 5', // safari版本大于等于5
'Android >= 4', // 安卓版本大于等于4
'Ios >= 6', // ios版本大于等于6
'last 4 version', // 浏览器当前最新的4个版本
]
}),
]
}
}
],
}
]
}
浏览器设置也可以放在package.json里边(package.config.js 里需要删掉require('autoprefixer')后面的配置传参)
注意:package.json文件里不能有注释
'browserslist': [
'ie >= 8',
'Firefox >= 20',
'Safari >= 5',
'Android >= 4',
'Ios >= 6',
'last 4 version'
]
使用sourceMap
js的sourcemap 通过设置 webpack.config.js 的 devtool属性 来实现,可选值有以下这些:
总体来说分为五个类型:(真正的属性值是以下这些特性的组合)
1.eval
每个模块都用eval()执行,每个模块后加sourceURL来关联模块处理前后的对应关系
由于会映射到转换后的代码, 而不是映射原始代码,(没有从loader中获取sourceMap)所以不能正确的显示行数。因为不需要生成sourcemap,所以速度快
2.source-map
source-map会为模块生成独立的sourcemap文件
打包后的模块会在后面对应引用一个.map文件同时打包好的文件夹下会生成响应的.map文件
3.Inline
与source-map不同的是,添加Inline属性后,不会生成.map文件,source-map转换为DataUrl后添加到bundle中
4.cheap
cheap属性会为打包后的文件生成.map文件但是与source-map不同的是cheap的.map会忽略原始代码中的列信息,也不包含loader的sourcemap
5.module
包含了loader之间的sourcemap,将loader source map简化为每行一个映射
#### 一般的