webpack入门
webpack的几个基本的概念
webpack安装
1.先初始化一个文件
cd 当前目录 npm init //初始化一下 会产生一个 package.json 文件 之后提示不用管 //一路回车 直到... About to write to 目录\package.json: { "name": "...", "version": "1.0.0" ... } Is this ok? (yes) //回车 完成 安装webpack npm install webpack --save-dev npm install webpack-cli --save-dev //webpack4.+ 版本需要安装webpack-cli
mode开发模式
webpack 提供 mode 配置选项,配置 webpack 相应模式的内置优化。
webpack.config.js
module.exports = {
mode: "production", //产品模式 会压缩和优化
mode: "development", //开发模式
mode: "none", // no defaults
}
入口文件
entry 对象是用于 webpack 查找启动并构建 bundle。其上下文是入口文件所处的目录的绝对路径的字符串。
webpack.config.js
module.exports = {
entry: "./app/entry", // string | object | array
entry: ["./app/entry1", "./app/entry2"],
entry: {
a: "./app/entry-a",
b: ["./app/entry-b1", "./app/entry-b2"]
},
}
输出(output)
output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件。
webpack.config.js
const path = require('path');
module.exports = {
output: {
// webpack 如何输出结果的相关选项
path: path.resolve(__dirname, "dist"), // string
//__dirname 以当前目录下产生一个 dist
// 所有输出文件的目标路径
// 必须是绝对路径(使用 Node.js 的 path 模块)
filename: "bundle.js", // string
filename: "[name].js", // 用于多个入口点(entry point)(出口点?)
filename: "[chunkhash].js", // 用于长效缓存
// 「入口分块(entry chunk)」的文件名模板(出口分块?)
publicPath: "/assets/", // string
publicPath: "",
publicPath: "https://cdn.example.com/",
// 输出解析文件的目录,url 相对于 HTML 页面
library: "MyLibrary", // string,
// 导出库(exported library)的名称
libraryTarget: "umd", // 通用模块定义
}
}
服务配置
开发中希望通过localhost方式访问,或者IP地址来访问
//安装webpack内置的开发服务 运行npm install webpack-dev-server --save-dev npm install webpack-dev-server --save-devwebpack.config.jsconst path = require('path'); module.exports = { devServer: { //开发服务器的配置 port: 3000, //修改端口号 progress: true, //内存打包出现进度条 contentBase: './bulid', //以build 目录作为静态服务 open: true, //自动打开浏览器 compress: true,//启用gzip压缩 }, } //运行时 npm webpack-dev-server //webpack-dev-server 命令也可以在packge.json 文件里面进行配置packge.json{ "name": "webpack-dev-1", ... "scripts": { "build": "webpack --config wepack.config.min.js", "dev": "webpack-dev-server" }, "devDependencies": { .... } } //运行时 npm dev 即可
跨域问题
//安装webpack内置的开发服务 运行npm install webpack-dev-server --save-dev
npm install webpack-dev-server --save-dev
webpack.config.js
const path = require('path');
module.exports = {
devServer: { //开发服务器的配置
...
proxy:{//解决跨域问题
'/api': {
target: 'http://localhost:3000',
pathRewrite: {'/api': ''}
}
}
},
}
loader
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。
在更高层面,在 webpack 的配置中 loader 有两个目标:
1. test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
2. use 属性,表示进行转换时,应该使用哪个 loader。
//先安装 less-loader 和 style-loader
npm install css-loader style-loader --save-dev
webpack.config.js
module.exports = {
module: {//模块
noParse: /jquery/,//不想解析jquery,因为jquery没有依赖
rules: [//规则 css-loader 解析@import这种语法
//style-loader 把css插入到 head 标签中
//loader 用法 字符串 只用一个loader
//多个loader需要用数组 []
//也可用对象形式 用对象的好处是可以传参
//loader 的执行顺序是从右(下)向左(上)
//其他css一样
//sass node-sass sass-loader
//stylus stylus-loader
{ test: /\.txt$/, use: 'raw-loader' },
{ test: /\.css$/, use:['style-loader', 'css-loader']},
{ test: /\.less$/,
use:[//对象形式
{
loader:'style-loader',
options:{//传参
//希望把生成的样式插入到head的顶部,这样就不会覆盖自己写的默认样式
insertAt: 'top',
}
},
'css-loader',
'less-loader' //先安装 npm install less less-lodaer --save-dev
]
},
{text: /\.js$/,
exclude: /node_modules/,//排除node_modules目录下的.js
include:path.resolve('src'),//只找src目录下的.js
use: {
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'//解析react语法
]
}
}
}
]
}
}
以上配置中,对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:test 和 use。这告诉 webpack 编译器(compiler) 如下信息:
“嘿,webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先使用 raw-loader 转换一下。”
源码映射source-map
解决开发代码与实际运行代码不一致时帮助我们debug到原始开发代码的技术,简单来说可以用来调试功能
webpack.config.js
module.exports = {
//1) 源码映射,会产生一个单独的文件,出错了,会标识当前报错的行和列
devtool: 'source-map',//增加映射文件,可以帮我们调试源代码
//2)源码映射,不会产生一个单独的文件,出错了,会标识当前报错的行和列
devtool: 'eval-source-map',//增加映射文件,可以帮我们调试源代码
//3)源码映射,会产生一个单独的文件,出错了,不会标识当前报错的行和列
devtool: 'cheap-module-source-map',//产生后可以保留起来
//4)源码映射,不会产生文件,继承在打包后的文件,不会标识当前报错的行和列
devtool: 'cheap-module-eval-source-map',
plugins:[...]
}
监控watch
自动打包,每当监控到代码改动时,实时重新执行打包
webpack.config.js
module.exports = {
watch: true,
watchOptions: {//监控的选项
poll: 1000, //每秒监控1000次
aggregateTimeout: 500,防抖 ,停止输入后的500毫秒打包
ignored: /node_modules/, //不需要监控这个文件
}
}
解析
配置模块如何解析。比如: import _ from 'lodash' ,其实是加载解析了lodash.js文件。此配置就是设置加载和解析的方式。
webpack.config.js
module.exports = {
resolve: {
//只在node_modules目录里查找,可多写
modules: [path.resolve('node_modules'),path.resolve('dist')],
alias:{//别名
bootstrap: 'bootstrap/dist/css/bootstrap.css'
},
mainFields: ['style','main'],//主入口,先找style,,找不到再去mian里面找
mainFiles: [],//入口文件的名字 默认找index.js
extensions:['.js','.css','.json'],//扩展名先找.js,没有再找.css,没有再找.json
}
}
插件
想要使用一个插件,你只需要require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。
【插件】自动打包生成
webpack.config.js
const path = require('path');
//通过 npm 安装 npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
output: {
filename:'bundle.[hash].js',//给文件加哈希 防止缓存
filename:'bundle.[hash:8].js',//给文件加8位哈希
path: path.resolve(__dirname, "dist"),
}
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html', //以谁作为模板
filename: 'index.html', //打包出来的文件名称
minify:{ //压缩
removeAttributeQuotes: true,//删除html里的双引号
collapseWhitespace: true,//压缩为一行
},
hash: true,//添加哈希戳
})
]
}
【插件】多页面自动打包生成
webpack.config.js
const path = require('path');
//通过 npm 安装 npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
home: "./src/index.js",
other: "./src/other.js"
},
output: {
filename:'[name].js',//[name] 相当于home 和 other
path: path.resolve(__dirname, "dist")
}
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html', //以谁作为模板
filename: 'home.html', //打包出来的文件名称
chunks: ['home'],//表示home.html页面只引入home.js
minify:{ //压缩
removeAttributeQuotes: true,//删除html里的双引号
collapseWhitespace: true,//压缩为一行
}
}),
new HtmlWebpackPlugin({
template: './src/index.html', //以谁作为模板
filename: 'other.html', //打包出来的文件名称
chunks: ['other','home'],//表示home.html页面引入other.js和home.js
minify:{ //压缩
removeAttributeQuotes: true,//删除html里的双引号
collapseWhitespace: true,//压缩为一行
}
})
]
}
【插件】每次清空打包目录
webpack.config.js
//先安装 npm install clean-webpack-plugin --save-dev const CleanWebpackPlugin = require('clean-webpack-plugin') module.exports = { .. plugins: [ ... new CleanWebpackPlugin('/dist') //需要清空的目录文件 ] }
【插件】复制一些文件到目标目录打包
webpack.config.js
//先安装 npm install copy-webpack-plugin --save-dev const CopyWebpackPlugin = require('copy-webpack-plugin') module.exports = { .. plugins: [ ... new CopyWebpackPlugin([ {from: '/doc',to: './dist'},//从文件doc复制到dist文件夹 ]) ] }
【插件】添加版权
webpack.config.js
//webpack内置,不用安装
module.exports = {
..
plugins: [
...
new webpack.BannerPlugin('这里写版权信息')
]
}
其他
自定义 webpack.config.js文件
//方法1 --在运行时 指定自定义的文件名称
npx webpack --config wepack.config.min.js //--config 后面跟自定义的文件名称
//方法2 --在packge.json 文件里面进行配置
packge.json
{
"name": "webpack-dev-1",
...
"scripts": {
"build": "webpack --config wepack.config.min.js"
},
"devDependencies": {
....
}
}
//build 是自定义的命令
//然后运行 npm run build