一、webpack基本安装
1、创建webpack项目目录如webpackDemo,并进入webpackDemo;
2、 在node已经安装的前提下,打开命令行控制器,输入如下命令:
npm init -y npm install webpack webpack-cli --save-dev //安装webpack webpack-cli
(MacOS: sudo npm install webpack webpack-cli -g,sudo npm isntall webpack webpack-cli --save-dev)
命令执行结束后,会生成package.json、package_lock.json、node_modules文件。然后手动创建src目录与package.json平级,src目录下有index.html ,index.js 。
注:npm使用的是淘宝镜像,使用命令 npm install --registry=https://registry.npm.taobao.org express (临时使用);
(MacOS 如果上面命令不生效,可以使用此命令: npm config set registry https://registry.npm.taobao.org).
二、webpack概念
1、 webpack有四个核心概念:entry(入口) 、output(输出)、loader、plugin(插件)。
entry(入口)
告诉webpack构建内部依赖图开始的模块;可以指定单入口起点文件或多入口起点文件。
module.exports = { entry:"./src/index.js" }
output(输出)
告诉webpack输出创建的bundles,以及如何命名文件。指定编译后的输出文件路径。
const OUTPUT_FILE_NAME = "dist" module.exports = { entry:"./src/index.js", output: { filename: "[name].[contenthash:10].js", //输出文件名称, hash解决缓存问题 path: path.resolve(__dirname,‘dist‘) //输出文件路径 } }
loader
loader可以让webpack可以处理非JavaScript文件,webpack本身只能处理JavaScript。
webpack配置loader有两个目标:
a). test属性,用于被对应的loader进行转换的某个和某些文件;
b). use属性,表示进行转换时,应该使用哪个loader;
module.exports = { output: { filename: "[name].[contenthash:10].js", //输出文件名称, hash解决缓存问题 path: path.resolve(__dirname, OUTPUT_FILE_NAME) //输出文件路径 }, module: { rules: [{ //整理html的img资源, test: /\.html$/, use: ["html-loader"] }, { //处理css资源 test: /\.css$/, use: ["css-loader", "style-loader"] }, { //处理JS资源 test: /\.jsx?$/, use: [‘file-loader‘] }] } }
插件plugins
loader用于转换某些类型,插件用于执行更广泛的任务。若使用一个插件,只需require(),然后添加到数组中。
module.exports = { ..., plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", hash: true }), new MiniCssExtarctPlugin({ filename: ‘css/[name].[contenthash:10].css‘, path: path.resolve(__dirname,‘dist‘) }) ] }
附全部代码:
package.json
{ "name": "webpack_demo", "version": "1.0.0", "description": "", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "watch": "webpack --watch", "start": "webpack --config webpack.config.js", "build": "webpack --config webpack.config.pro.js" }, "keywords": [], "author": "", "license": "ISC" }
webpack.config.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtarctPlugin = require("mini-css-extract-plugin"); //将css从js中提取出来 const OUTPUT_FILE_NAME = "dist"; module.exports = { entry: "./src/index.js", output: { filename: "[name].[contenthash:10].js", //输出文件名称,hash解决缓存问题,具体可见下面的解释 path: path.resolve(__dirname, OUTPUT_FILE_NAME) //输出文件路径 }, mode: "development", //开发环境,生产环境使用"production" module: { rules: [{ //整理html的img资源, test: /\.html$/, use: ["html-loader"] }, { //处理css资源 test: /\.css$/, use: [ //将css文件整合到JS文件中 "css-loader", //创建style标签,将样式放入 "style-loader", // css兼容性处理:postcss-->postcss-loader postcss-preset-env ] }, { //处理JS资源 test: /\.js$/, exclude: /node_modules/, //处理除了nodde_modules里的js文件 loader: ‘babel-loader‘ //用babel-loader处理 }, { //处理图片资源 test: /\.(png|svg|jpg|gif)$/, use: [‘file-loader‘] }, { // exclude: /\.(css|js|html)$/, //排除正则内的资源 test: /\.(png|svg|jpg|gif)$/, // 这里是匹配条件,每个选项都接收一个正则表达式或字符串 // test 和 include 具有相同的作用,都是必须匹配选项 // exclude 是必不匹配选项(优先于 test 和 include) // 最佳实践: // - 只在 test 和 文件名匹配 中使用正则表达式 // - 在 include 和 exclude 中使用绝对路径数组 // - 尽量避免 exclude,更倾向于使用 include use: [‘file-loader‘], // options: { // name: "[hash:10].[ext]" //名字太长进行截取 // } } ] }, resolve: { extensions: [‘.js‘, ‘.json‘] }, /* source-map:外联 inline-source-map : */ devtool: "source-map", //告诉webpack提供源代码 plugins: [ // 将CSS文件从JS文件中提取出来 new MiniCssExtarctPlugin({ filename: ‘css/[name].[contenthash:10].css‘, path: path.resolve(__dirname, OUTPUT_FILE_NAME) }), new HtmlWebpackPlugin({ template: "./src/index.html" }) ], devServer: { port: 5000, //端口号 contentBase: OUTPUT_FILE_NAME, //可访问问文件 hot: true, //开启HMR热更新 https: true, //使用https compress: true, // 启用压缩 // proxy: { // "/": "http://localhost:3000", //使用代理路径 // } }, /** code splitting 代码分割 * 当单入口时,可以将 node_modules中代码单独打包成一个chunk; * 当多入口时,提取公共文件单独打包成一个chunk; */ optimization: { splitChunks: { chunks: "all" } } /** * 缓存: * Babel缓存 * cacheDirectory:true * -->让第二次打包更快 * 文件资源缓存: * hash :每次webpack构建是会生成一个唯一的hash值; * 问题:js和css使用同一个hash值,会导致缓存失效,可能值改变一个文件; * chunkhash:根据chunk生成的hash值,如果打包来自同一个chunk,那么hash是一样的 * 问题:chunkhash是一样的,因为css是在js中被引用的,属于同一个chunk; * contenthash:根据文件内容生成hash值,不同文件的hash值不一样; * -->让代码上线运行缓存更好使用 * */ /** * tree shaking:去除无用代码 * 前提: 1.必须使用ES6模块化 2.开启production环境 * 作用: 减少代码体积 * * 在package.json中设置: * sideEffects:false 所有代码都没有副作用(都可以进行tree shaking) * 问题:可能会把css @babel/polyfill(副作用)文件干掉 * sideEffects:["*.css",".less"] 不会进行tree shaking */ /** * HMR :hot module replacement 热模块 * 作用:一个模块发生变化指挥重新打包这个模块,并不重新打包所有。提高打包速度。 * 样式文件:可以通过HMR实现,style-loader已实现 * JS文件:默认不使用HMR功能-->修改JS文件代码,只能处理非入口文件。 * if(module.hot){ * module.hot.accept("index.js",()=>{ * //监听文件变化,一旦发生变法,其他地方不会重新打包,直接执行回调 * })) * } * Html文件:默认不使用HMR功能,同时会出问题(无需做HMR功能) * 解决方案:修改entry入口,引入html文件 * * */ }
wenpack.config.pro.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtarctPlugin = require("mini-css-extract-plugin"); //将css从js中提取出来 const OptiminizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); //压缩CSS const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const OUTPUT_FILE_NAME = "dist"; module.exports = { entry: "./src/index.js", output: { filename: "js/[name].[contenthash:10].js", //输出文件名称,hash解决缓存问题,具体可见下面的解释 chunkFilename: ‘js/[name].[contenthash:10].bundle.js‘, // 依赖文件名称 path: path.resolve(__dirname, OUTPUT_FILE_NAME), //输出文件路径 publicPath: ‘/‘ // 公共路径 }, mode: "production", //生产环境 module: { rules: [{ test: /\.html$/, use: ["html-loader"] }, { test: /\.css$/, use: [MiniCssExtarctPlugin.loader, "css-loader"] }, { test: /\.jsx?$/, exclude: /node_modules/, //处理除了nodde_modules里的js文件 loader: ‘babel-loader‘ //用babel-loader处理es6 }, { test: /\.(png|svg|jpg|gif)$/, use: [‘file-loader‘], } ] }, devtool: "source-map", //告诉webpack提供源代码 plugins: [ new HtmlWebpackPlugin({ template: "./src/index.html", hash: true }), new MiniCssExtarctPlugin({ filename: ‘css/[name].[contenthash:10].css‘, path: path.resolve(__dirname, OUTPUT_FILE_NAME) }), /** * optimize-css-assets-webpack-plugin 会使webpack中自带的JS压缩失效,需要重新配置UglifyJsPlugin */ new OptiminizeCssAssetsPlugin(), ], /** code splitting 代码分割 * 当单入口时,可以将 node_modules中代码单独打包成一个chunk; * 当多入口时,提取公共文件单独打包成一个chunk; */ optimization: { splitChunks: { chunks: "all" } } }