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.js
const 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