# webpack_default **Repository Path**: djxu/webpack_default ## Basic Information - **Project Name**: webpack_default - **Description**: webpack基本配置 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-11-17 - **Last Updated**: 2022-04-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: webpack ## README # WEBPACK **`注:webpack 是一个现代 JavaScript 应用程序的静态模块打包器,当 webpack 处理应用程序时,会递归构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将这些模块打包成一个或多个 bundle。`** ## 1、webpack 的核心概念 1. entry: 入口 2. output: 输出 3. loader: 模块转换器,用于把模块原内容按照需求转换成新内容 4. 插件(plugins): 扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要做的事情 ## 2、初始化项目 1. 使用 npm init -y 进行初始化 2. npm install webpack webpack-cli -D 要使用 webpack,那么必然需要安装 webpack、webpack-cli ## 3、构建项目 npx webpack --mode=development 进行构建,默认是 production 模式,我们为了更清楚得查看打包后的代码,使用 development 模式。 webpack 有默认的配置,如默认的入口文件是 ./src,默认打包到dist/main.js ## 4、将JS转义为低版本 loader 用于对源代码进行转换,将JS代码向低版本转换,我们需要使用 babel-loader ``` npm install babel-loader -D ``` 还需要配置 babel,为此我们安装一下以下依赖: ``` npm install @babel/core @babel/preset-env @babel/plugin-transform-runtime -D npm install @babel/runtime @babel/runtime-corejs3 ``` ### 1、核心库 @babel/core > Babel 的核心功能包含在 @babel/core 模块中。看到 core 这个词了吧,意味着核心,没有它,在 babel 的世界里注定寸步难行。不安装 @babel/core,无法使用 babel 进行编译 ### 2、CLI命令行工具 @babel/cli ``` npm install --save-dev @babel/cli ``` 命令配置在 package.json 文件的 scripts 字段中: ``` "scripts": { "compiler": "babel src --out-dir lib --watch" } ``` ### 3、预设插件 @babel/preset-env 主要作用是对我们所使用的并且目标浏览器中缺失的功能进行代码转换和加载 polyfill,在不进行任何配置的情况下,@babel/preset-env 所包含的插件将支持所有最新的JS特性(ES2015,ES2016等,不包含 stage 阶段),将其转换成ES5代码。例如,如果你的代码中使用了可选链(目前,仍在 stage 阶段),那么只配置 @babel/preset-env,转换时会抛出错误,需要另外安装相应的插件。 ``` //.babelrc { "presets": ["@babel/preset-env"] } ``` 指定目标环境,这样你的编译代码能够保持最小。如下指定chorme最新两个版本 ``` //.browserslistrc last 2 Chrome versions ``` ### 4、polyfill 因为语法转换只是将高版本的语法转换成低版本的,但是新的内置函数、实例方法无法转换。这时,就需要使用 polyfill 上场了,顾名思义,polyfill的中文意思是垫片,所谓垫片就是垫平不同浏览器或者不同环境下的差异,让新的内置函数、实例方法等在低版本浏览器中也可以使用。 ### 5、@babel/plugin-transform-runtime @babel/plugin-transform-runtime 是一个可以重复使用 Babel 注入的帮助程序,以节省代码大小的插件。 ``` //.babelrc { "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 } ] ], "plugins": [ [ "@babel/plugin-transform-runtime" ] ] } ``` ## 5、在浏览器中查看页面 查看页面,难免就需要 html 文件,有小伙伴可能知道,有时我们会指定打包文件中带有 hash,那么每次生成的 js 文件名会有所不同,总不能让我们每次都人工去修改 html 首先,安装一下插件: ``` npm install html-webpack-plugin -D ``` 修改 webpack.config.js 文件 ``` const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { //... plugins: [ //数组 放着所有的webpack插件 new HtmlWebpackPlugin({ template: './public/index.html', filename: 'index.html', //打包后的文件名 minify: { removeAttributeQuotes: false, //是否删除属性的双引号 collapseWhitespace: false, //是否折叠空白 }, // hash: true //是否加上hash,默认是 false }) ] } ``` ### 1、html-webpack-plugin 的 config (动态配置html文件的title,css,js等) 在public 目录下新增一个 config.js ``` module.exports = { dev: { template: { title: '你好', header: false, footer: false } }, build: { template: { title: '你好才怪', header: true, footer: false } } } ``` 修改下webpack.config.js ``` const HtmlWebpackPlugin = require('html-webpack-plugin'); const isDev = process.env.NODE_ENV === 'development'; const config = require('./public/config')[isDev ? 'dev' : 'build']; modue.exports = { //... mode: isDev ? 'development' : 'production' plugins: [ new HtmlWebpackPlugin({ template: './public/index.html', filename: 'index.html', //打包后的文件名 config: config.template }) ] } ``` 修改下我们的 public/index.html ``` <% if(htmlWebpackPlugin.options.config.header) { %> <% } %> <%= (htmlWebpackPlugin.options.config.title) %> <% if(htmlWebpackPlugin.options.config.header) { %> <% } %> ``` process.env 中默认并没有 NODE_ENV,这里配置下我们的 package.json 的 scripts. 为了兼容Windows和Mac,我们先安装一下 cross-env: ``` npm install cross-env -D ``` ``` { "scripts": { "dev": "cross-env NODE_ENV=development webpack", "build": "cross-env NODE_ENV=production webpack" } } ``` ## 6、热更新 先装依赖 ``` npm install webpack-dev-server -D ``` 修改下package.json 文件的 scripts: ``` "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server", "build": "cross-env NODE_ENV=production webpack" }, ``` 配置 ``` devServer: { port: '3000', //默认是8080 quiet: false, //默认不启用 inline: true, //默认开启 inline 模式,如果设置为false,开启 iframe 模式 stats: "errors-only", //终端仅打印 error overlay: false, //默认不启用 clientLogLevel: "silent", //日志等级 compress: true //是否启用 gzip 压缩 } ``` ## 7、devtool devtool 中的一些设置,可以帮助我们将编译后的代码映射回原始源代码。不同的值会明显影响到构建和重新构建的速度。 ``` //webpack.config.js module.exports = { devtool: 'cheap-module-eval-source-map' //开发环境下使用 } ``` ## 8、处理样式文件 webpack 不能直接处理 css,需要借助 loader。如果是 .css,我们需要的 loader 通常有: style-loader、css-loader,考虑到兼容性问题,还需要 postcss-loader,而如果是 less 或者是 sass 的话,还需要 less-loader 和 sass-loader,这里配置一下 less 和 css 文件(sass 的话,使用 sass-loader即可): ``` npm install style-loader less-loader css-loader postcss-loader autoprefixer less -D ``` ``` //webpack.config.js module.exports = { //... module: { rules: [ { test: /\.(le|c)ss$/, use: ['style-loader', 'css-loader','postcss-loader', 'less-loader'], exclude: /node_modules/ } ] } } ``` .postcss.config.js 中写入一下 ``` module.exports={ plugins: { 'autoprefixer': { overrideBrowserslist: [ "Android 4.1", "iOS 7.1", "Chrome > 31", "ff > 31", "ie >= 8" //'last 2 versions', // 所有主流浏览器最近2个版本 ], grid: true } } } ``` 1. style-loader 动态创建 style 标签,将 css 插入到 head 中. 2. css-loader 负责处理 @import 等语句。 3. postcss-loader 和 autoprefixer,自动生成浏览器兼容性前缀 4. less-loader 负责处理编译 .less 文件,将其转为 css 5. loader 的执行顺序是从右向左执行的,也就是后面的 loader 先执行,上面 loader 的执行顺序为: less-loader ---> postcss-loader ---> css-loader ---> style-loader ## 9、图片/字体文件处理 我们可以使用 url-loader 或者 file-loader 来处理本地的资源文件。url-loader 和 file-loader 的功能类似,但是 url-loader 可以指定在文件大小小于指定的限制时,返回 DataURL,因此,个人会优先选择使用 url-loader。 ``` npm install url-loader -D npm install file-loader -D ``` ``` //webpack.config.js module.exports = { //... modules: { rules: [ { test: /\.(png|jpg|gif|jpeg|webp|svg|eot|ttf|woff|woff2)$/, use: [ { loader: 'url-loader', options: { limit: 10240, //10K esModule: false } } ], exclude: /node_modules/ } ] } } ``` 当本地资源较多时,我们有时会希望它们能打包在一个文件夹下,这也很简单,我们只需要在 url-loader 的 options 中指定 outpath,如: outputPath: 'assets' ## 10、入口配置 ``` //webpack.config.js module.exports = { entry: './src/index.js' //webpack的默认配置 } ``` 多入口 entry: [ './src/polyfills.js', './src/index.js' ] ## 11、出口配置 ``` const path = require('path'); module.exports = { entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), //必须是绝对路径 filename: 'bundle.js', publicPath: '/' //通常是CDN地址 } } ``` 考虑到CDN缓存的问题,我们一般会给文件名加上 hash. ``` //webpack.config.js module.exports = { output: { path: path.resolve(__dirname, 'dist'), //必须是绝对路径 filename: 'bundle.[hash].js', publicPath: '/' //通常是CDN地址 } } ``` ## 12、每次打包前清空dist目录 ``` npm install clean-webpack-plugin -D ``` ``` //webpack.config.js const { CleanWebpackPlugin } = require('clean-webpack-plugin'); module.exports = { //... plugins: [ //不需要传参数喔,它可以找到 outputPath new CleanWebpackPlugin() ] } ```