webpack 之 搭建 本地服务器 && 环境

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

webpack 之 使用 loader && babel

webpack 之 使用 plugin && mode

目录

一、开启本地服务器

1. 理由

2. 方式一 :wabpack watch

3. 方式二 :wabpack-dev-server ( 常用 )

1. 安装webpack-dev-server

2. 在package.json中配置

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

4. 现在能实时更新了

二、devServer 配置 DevServer | webpack

1. static/directory : 

2. HMR : 模块热替换 ( 重要 )

3. port

4. open

5. compress

6. host 

7. proxy配置

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

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

2. 修改package.json中的配置

3. webpack.comm.config.js配置

4. webpack-merge

5. webpack.dev.config.js配置

6. webpack.prod.config.js配置 


一、开启本地服务器

1. 理由

 之前开发的代码,为了运行需要两个步骤

  • 操作一:npm run build,编译相关的代码
  • 操作二:通过live server或者直接通过浏览器,打开index.html代码,查看效果

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

 

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

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

2. 方式一 :wabpack watch

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

 

ps : 这种方式事实上本身是没有自动刷新浏览器功能的(之前是因为有live-server)

开启watch也有两种方式

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

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

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

3. 方式二 :wabpack-dev-server ( 常用 )

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

 

ps : 运行后并不会生成本地的文件,打包到了内存里,没有输出出来,这是为了提高效率

1. 安装webpack-dev-server

npm install webpack-dev-server -D

2. 在package.json中配置

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

4. 现在能实时更新了

最后开发完成后,再自己npm run build一下生成打包文件即可

二、devServer 配置 DevServer | webpack

1. static/directory : 

  • 浏览器请求打包后的资源,如果没有请求到,会自动去这个文件夹进行查找(也就是说没有打包的资源,如果放到这个文件夹里,也能进行访问)

  • 可以进行动态配置,因为开发阶段时如果我们也在使用CopyWebpackPlugin插件,每次运行的效率就会比较低,所以开发阶段我们可以关闭CopyWebpackPlugin直接使用这个

  • 生产阶段的时候在打开CopyWebpackPlugin (这就涉及到动态配置了,可以使用)

  • 总而言之 开发阶段:使用这个 | 生产阶段:CopyWebpackPlugin

devServer: {
    static: {
      // 指定路径
      directory: path.join(__dirname, 'public')
    }
}

2. 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,
},

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

 

因为需要去指定哪些模块发生更新时,进行HMR

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

3. port

port设置监听的端口,默认情况下是8080

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

4. open

open是否打开浏览器 =>  默认值是false,设置为true会打开浏览器

// 配置服务
devServer: {
  static: {
    // 指定路径
    directory: path.join(__dirname, 'public')
  },
  //  模块热替换
  hot: true,
  // 设置端口号
  port: 9000,
  // 是否自动打开浏览器
  open: true
},

5. compress

compress是否为静态文件开启gzip compression =>  默认值是false

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

6. host 

host设置主机地址 : 

  • 默认值是localhost
  • 如果希望其他地方也可以访问,可以设置为 0.0.0.0

localhost 和 0.0.0.0 的区别 : 

  • localhost:本质上是一个域名,通常情况下会被解析成127.0.0.1
  • 127.0.0.1:回环地址(Loop Back Address),表达的意思其实是我们主机自己发出去的包,直接被自己接收
    • 正常的数据库包经常 应用层 - 传输层 - 网络层 - 数据链路层 - 物理层
    • 而回环地址,是在网络层直接就被获取到了,是不会经常数据链路层和物理层的
    • 比如我们监听 127.0.0.1时,在同一个网段下的主机中,通过ip地址是不能访问的
  • 0.0.0.0:监听IPV4上所有的地址,再根据端口找到不同的应用程序
    • 比如我们监听 0.0.0.0时,在同一个网段下的主机中,通过ip地址是可以访问的
devServer: {
  //  模块热替换
  hot: true,
  // 设置端口号
  port: 9000,
  // 是否自动打开浏览器
  open: true,
  // 启动gzip压缩
  compress: true,
  // host配置
  host: '0.0.0.0'
},

7. proxy配置

 // 配置服务
  devServer: {
    static: {
      // 指定路径
      directory: path.join(__dirname, 'public')
    },
    //  模块热替换
    hot: true,
    // 启动gzip压缩,传输速率会变快
    compress: true,
    // 自动打开浏览器
    open: true,
    // 设置主机地址,默认是localhost,如果希望其他地方也可以访问,可以设置为 '0.0.0.0'
    // 其他地方访问:通过你电脑的ip地址加上端口来访问的
    // 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' },
    //   ],
    // },
  },

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

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

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'
            ]
          }
        }
      ]
    })
  ]
});
  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值