0


webpack 之 零基础使用Babel、搭建环境、resolve模块,超详细


大家可以先去看我的前两篇文章,顺便可以点个三连哦,嚯嚯嚯~

  1. webpack 之 零基础使用常用的Loader
  2. webpack 之 零基础使用常用的Plugin

Babel : Babel · The compiler for next generation JavaScript

首先我们得了解一下babel的一些基本概念

一、什么是babel

  • Babel是一个工具链
  • 主要用于旧浏览器后者环境中将ECMAScript 2015+ ( ES6+ )的代码转换为向后兼容的JavaScript
  • 包括 : 语法转换、源代码转换等

二、为什么需要babel呢

  • babel对于前端开发来说,是不可缺少的一部分
  • 开发中,如果我们想使用ES6+的语法,想要使用TypeScript,开发React项目,都离不开****Babel

三、babel的底层原理

  • 从一种源代码(原生语言)转换成另一种源代码(目标语言)
  • 事实上我们可以吧babel看成就是一个编译器
  • babel编译器的作用就是将我们的源代码,转换成浏览器可以直接识别的另外一段源代码

babel的工作流程:解析阶段、转换阶段、生成阶段

具体一点

ok啦,接下来我们就可以开始打代码了!!!


** **四、使用babel

**babel可以用来转换,但是是通过具体的babel插件来完成的,所以我们不仅要下载babel,也需要下载你所需要的对应的插件 **

**1.**下载babel-loader和babel-core

npm install babel-loader @babel/core -D

2.下载对应的插件

@babel/plugin-transform-arrow-functions : 箭头函数转换插件

@babel/plugin-transform-block-scoping : 作用域转化插件 (const、let 关键字转换为 var)

npm install @babel/plugin-transform-arrow-functions -D
npm install @babel/plugin-transform-block-scoping -D

3.在src文件夹的js文件夹夹创建es.js

随便乱写点ES6新增的,如cosnt、剪头函数等

const message = 'hello world';
const names = [123, 321];

names.forEach((item) => console.log(item));

console.log(message);

4.在index.js中导入

import './js/es';

5.在webpack.config.js中进行配置

tip : 因为现在代码越来越多啦,全弄上来怕你们找不到在哪里,所以就先截图,然后在把代码放进去了哈~

// js文件
{
  test: /\.js$/,
  use: [
    {
      // 使用loader
      loader: 'babel-loader',
      options: {
        // 使用的插件
        plugins: ['@babel/plugin-transform-arrow-functions', '@babel/plugin-transform-block-scoping']
      }
    }
  ]
}

6.查看效果

7.优化

因为这两个插件都是很常用的,还有一些其他常用的插件,如果我们每次都一个个去下载未免太累了,可以直接给webpack提供一个preset,webpack会根据预设来加载对应的插件列表,并传递给babel

常见的预设有 : env、react、TypeScript

**@babel/preset-env : **里面自带了ES6转换相关的插件

npm install @babel/preset-env -D

所以代码就可以修改成这样啦

// js文件
{
  test: /\.js$/,
  use: [
    {
      // 使用loader
      loader: 'babel-loader',
      options: {
        // 使用的插件
        // plugins: ['@babel/plugin-transform-arrow-functions', '@babel/plugin-transform-block-scoping']
        presets: ['@babel/preset-env']
      }
    }
  ]
}

8.再次优化 ,babel的配置文件

tip : 有多种后缀名,区别就是文件里的格式不一样,这里以.js后缀名为例子

  • 在根目录下新建babel.config.js
module.exports = {
  presets: ['@babel/preset-env']
};
  • webpack.config.js中即可改成这样
// js文件
{
  test: /\.js$/,
  use: ['babel-loader']
}

五、搭建环境

为什么要搭建本地环境呢? 之前我们开发的代码,为了运行需要两个步骤

  1. npm run buld,编译代码
  2. 通过 live server 或者直接通过浏览器,打开index.html

这样效率太慢了,所以我们希望当文件变化时,可以自动完成编译和展示

为了完成自动编译,webpack提供了几种可选的方式

  • webpack watch mode
  • webpack-dev-server(常用)

方式一 :wabpack watch

在该模式下,webpack依赖图中的所有文件,只要有一个发生了更新,那么代码会被重新编译,我们不需要手动去运行npm run build

开启watch也有两种方式

  • 在导出的配置中,添加 watch : true

  • 在package.json中,把以前写的那个打包的命令后加上 -- watch

这样后是不是发现下方变成了这样 ,两种方式用一个即可

方式二 :wabpack-dev-server

上面的方式可以监听到文件的变化而打包,但是事实上本身是没有自动刷新浏览器功能的(之前是因为有live-server)

wabpack-dev-server具备自动打包和实现监听功能

1.安装webpack-dev-server

npm install webpack-dev-server -D

2.在package.json中配置

3.使用npm run serve !!!!!!

4.现在能实时更新了

但是有个细节,现在的dist文件夹是空的,其实是打包了的,不过是打包到了内存里,没有输出出来 ,这是为了提高效率。最后开发完成后,再自己npm run build一下就好啦

5.可以进行些许配置 DevServer | webpack

我这里列举一些常使用的配置

** 一。static/directory : **

  • 浏览器请求打包后的资源,如果没有请求到,会自动去这个文件夹进行查找(也就是说没有打包的资源,如果放到这个文件夹里,也能进行访问)
  • 可以进行动态配置,因为开发阶段时如果我们也在使用CopyWebpackPlugin插件,每次运行的效率就会比较低,所以开发阶段我们可以关闭CopyWebpackPlugin直接使用这个
  • 生产阶段的时候在打开CopyWebpackPlugin (这就涉及到动态配置了,可以使用)
  • 总而言之 开发阶段:使用这个 生产阶段:CopyWebpackPlugin

二。HMR : 模块热替换

  • HMR => Hot Module Replacement
  • 指在应用程序运行过程中,替换、添加、删除模块,而无需刷新整个页面
  • 好处一 : 不重新加载整个页面,可以保留某些应用程序状态不丢失
  • 好处二 : 只更新需要变化的内容,节省开发的时间

原理(理解即可)

  • webpack-dev-server会创建两个服务:提供静态资源的服务(express)socket服务(net.socket)
  • express server扶着直接提供静态资源的服务(打包后的资源直接被浏览器请求和解析)
  • HTM Socket Server ,是一个socket的长链接
  • 当服务器监听到对应的模块发生改变时,会生成两个.json文件
  • 通过长链接,直接将这两个文件发送给客户端(浏览器
  • 浏览器拿到文件后,加载这两个文件,针对修改的模块进行更新

webpack-dev-serve已经支持了HMR,我们只需要开启即可

如果不开启,当我们修改代码后****,整个页面会自动刷新,使用的是live-reloading

tip : 最好同时使用target配置

配置地方在此

// 配置服务
devServer: {
  static: {
    // 指定路径
    directory: path.join(__dirname, 'public')
  },
  //  模块热替换
  hot: true,
  // 启动gzip压缩
  compress: true,
  // 设置端口号
  port: 9000
},

其实这样配置后,hot还是不生效,页面还是会刷新~,是因为引入的方式还要改,可恶

但是我们真实开发是不需要这样的,使用vue,react框架的时候,vue-loader等会自动支持hot,不需要我们自己来写,所以,我们只需要了解一下即可

三。proxy配置

 // 配置服务
  devServer: {
    static: {
      // 指定路径
      directory: path.join(__dirname, 'public')
    },
    //  模块热替换
    hot: true,
    // 启动gzip压缩,传输速率会变快
    compress: true,
    // 自动打开浏览器
    open: true,
    // 设置主机地址,默认是localhost,如果希望其他地方也可以访问,可以设置为 '0.0.0.0'
    // host: '0.0.0.0',
    // 设置端口号
    port: 9000,
    // 配置代理,解决代理问题
    proxy: {
      // 当遇到'/api'的时候
      '/api': {
        // 将目前的地址代理至target
        target: 'http://localhost:8888',
        // 将'/api' 重写为''
        pathRewrite: {
          '^/api': ''
        },
        // 设置允许访问https的服务器
        secure: false,
        // 在某些情况下会很有用
        changeOrigin: true
      }
    },
    // 设置为true时,路由跳转如果返回了404错误,会自动返回index.html的内容
    historyApiFallback: true
    // 也可以设置成一个对象,根据from来匹配路径,决定跳转到哪个页面
    // historyApiFallback: {
    //   rewrites: [
    //     { from: /^\/$/, to: '/views/landing.html' },
    //     { from: /^\/subpage/, to: '/views/subpage.html' },
    //     { from: /./, to: '/views/404.html' },
    //   ],
    // },
  },

六、resolve模块解析 : 解决路径相关

extensions : 配置后,就不用写对应的后缀名了

alias : 配置别名,就不用写很多类似 ../ ../../../ 之类的相对路径了

// 模块解析
resolve: {
  // 这些后缀名不用写
  extensions: ['.js', '.json', '.vue', '.css'],
  // 配置别名
  alias: {
    '@': path.resolve(__dirname, './src'),
    commonImg: path.resolve(__dirname, './src/img')
    // ...
  }
},

七、如何区分开发环境 :优化

优化:把开发环境和生产环境所需的各个配置分离!!!!!!

1.在根目录创建config文件夹,并创建几个文件

2.修改package.json中的配置

可以进行配置执行的文件

build : 打包的时候,加载生产环境所需配置

serve : 开发的时候,加载开发环境所需配置

"scripts": {
   "build": "webpack --config ./config/webpack.prod.config.js", 
   "serve": "webpack serve --config ./config/webpack.dev.config.js"
},

3.webpack.comm.config.js配置

const path = require('path'); // Node内置模块

// 插件的导入方式可能不同,具体查看文档哦
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 结构出来
const { DefinePlugin } = require('webpack');

module.exports = {
  // 因为当前代码环境跑在web上,进行配置一下
  target: 'web',
  // 入口
  entry: './src/index.js',
  // 出口
  output: {
    path: path.resolve(__dirname, '../dist'), // 因为这里需要绝对路径,__dirname获取到的是当前文件所在路径,所以拼接一下
    filename: 'js/boundle.js' // 打包后的js的文件名
  },
  // 模块解析
  resolve: {
    // 这些后缀名不用写
    extensions: ['.js', '.json', '.vue', '.css'],
    // 配置别名
    alias: {
      '@': path.resolve(__dirname, '../src'),
      commonImg: path.resolve(__dirname, '../src/img')
      // ...
    }
  },
  // 配置模块
  module: {
    // 规则
    rules: [
      // css|less文件
      {
        test: /\.(css|less)$/, // 用正则表达式来进行匹配,匹配css|less文件
        use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader']
      },
      // 图片
      {
        test: /\.(png|jpe?g|gif|svg)$/i, // 用正则表达式来进行匹配,匹配以这些后缀名的图片
        // 自动选择
        type: 'asset',
        parser: {
          // 数据url的条件配置
          dataUrlCondition: {
            // 超过100kb的图片打包,小于的弄成bast64
            maxSize: 10 * 1024
          }
        },
        // 生成
        generator: {
          filename: 'img/[name]__[hash:8][ext]'
        }
      },
      // 字体文件
      {
        test: /\.(eot|ttf|woff2?)$/i, // 用正则表达式来进行匹配,匹配以这些后缀名的字体文件
        type: 'asset/resource',
        // 生成
        generator: {
          filename: 'font/[name]__[hash:8][ext]'
        }
      },
      // js文件
      {
        test: /\.js$/,
        use: ['babel-loader']
      }
    ]
  },
  // 配置插件,放置着一个个的插件对象
  plugins: [
    // 生成index.html文件,并使用模版
    new HtmlWebpackPlugin({
      // 指定模版路径
      template: './public/index.html',
      // 顺便定义一下title
      title: '超级无敌巨帅小流星'
    }),
    // 定义变量
    new DefinePlugin({
      // 这里需注意  如果只有一层引号,那么内部会去找这个变量,所以如果要写字符串的话,里面再套一层,望周知
      BASE_URL: '"./"'
    })
    // new VueLoaderPlugin()
  ]
};

4.webpack-merge

因为不管是生产环境,还是开发环境,都需要公共的部分,所以需要合并,合并需要一个插件

npm install webpack-merge -D

5.webpack.dev.config.js配置

const path = require('path'); // Node内置模块
const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.comm.config');
// 合并
module.exports = merge(commonConfig, {
  // 设置模式
  mode: 'development',
  // 设置source-map,建立js映射文件,方便调试代码和错误
  devtool: 'source-map',
  // 配置服务
  devServer: {
    static: {
      // 指定路径
      directory: path.join(__dirname, './public')
    },
    //  模块热替换
    hot: true,
    // 启动gzip压缩,传输速率会变快
    compress: true,
    // 自动打开浏览器
    open: true,
    // 设置主机地址,默认是localhost,如果希望其他地方也可以访问,可以设置为 '0.0.0.0'
    // host: '0.0.0.0',
    // 设置端口号
    port: 9000,
    // 配置代理,解决代理问题
    proxy: {
      // 当遇到'/api'的时候
      '/api': {
        // 将目前的地址代理至target
        target: 'http://localhost:8888',
        // 将'/api' 重写为''
        pathRewrite: {
          '^/api': ''
        },
        secure: false,
        // 在某些情况下会很有用
        changeOrigin: true
      }
    },
    // 设置为true时,路由跳转如果返回了404错误,会自动返回index.html的内容
    historyApiFallback: true
  }
});

6.webpack.prod.config.js配置

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const { merge } = require('webpack-merge');
const commonConfig = require('./webpack.comm.config');
// 合并
module.exports = merge(commonConfig, {
  // 设置模式
  mode: 'production',
  plugins: [
    // 自动清空dist文件夹并重新生成
    new CleanWebpackPlugin(),
    new CopyWebpackPlugin({
      // 匹配你要复制的文件
      patterns: [
        {
          // 入口
          from: './public',
          to: './public',
          globOptions: {
            // 忽略的文件
            ignore: [
              // public文件夹下所有的index.html文件都被忽略,不复制
              '**/index.html'
            ]
          }
        }
      ]
    })
  ]
});

兄弟们,webpack就告一断落了,后面如果可以再继续更新,大家一起加油!!!

标签: webpack javascript

本文转载自: https://blog.csdn.net/a15297701931/article/details/124728699
版权归原作者 玄鱼殇 所有, 如有侵权,请联系我们删除。

“webpack 之 零基础使用Babel、搭建环境、resolve模块,超详细”的评论:

还没有评论