从脚手架开始学前端 【第8期】自制的Vue脚手架(持续更新)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 从脚手架开始学前端 【第5期】Vue脚手架搭建中,我们已经学到了如何使用Vue官网提供的vue-cli可以快速搭建一个项目,但是对于其中的原理方面我们还不是很清楚,今天我们就动手搭建自己vue开发环境,今天我们使用 webpack4来一步一步搭建自己的vue开发环境,如果还对webpack不熟悉的小伙伴,可以直接到官网传送门

前言


从脚手架开始学前端 【第5期】Vue脚手架搭建中,我们已经学到了如何使用Vue官网提供的vue-cli可以快速搭建一个项目,但是对于其中的原理方面我们还不是很清楚,今天我们就动手搭建自己vue开发环境,今天我们使用 webpack4来一步一步搭建自己的vue开发环境,如果还对webpack不熟悉的小伙伴,可以直接到官网传送门


准备


  • 安装node环境
  • 安装npm包管理
  • 安装yarn


配置内容


  • ES6/7/8/……代码转换成ES5代码
  • scss/sass/less/stylus转css
  • .vue文件转换成js文件
  • 使用 jpg、png,font等资源文件
  • 自动添加css各浏览器产商的前缀
  • 代码热更新
  • 资源预加载
  • 每次构建代码清除之前生成的代码
  • 定义环境变量
  • 区分开发环境打包跟生产环境打包

搭建流程


一、创建项目


创建项目目录并初始化项目

$ mkdir vue-cli-demo && cd vue-cli-demo && yarn init -y

打开package.json

{
  "name": "vue-cli-demo",
  "version": "1.0.0",
  "main": "index.js",
  "repository": "https://github.com/xunzhaotech/vue-cli-demo.git",
  "author": "xunzhaotech
  "license": "MIT"
}


二、安装


在webpack4后,webpack-cli从webpack包里面分离出来了,所以需要自己安装啦!


2.1安装webpack(推荐局部安装)


// 全局卸载
$ yarn global remove webpack
// 局部卸载
$ yarn remove webpack
// 全局安装
$ yarn add webpack -g      //-g 代表全局安装
// 局部安装
$ yarn add webpack -S      //-S是-save的缩写
$ yarn add webpack -D      //-D 是--save-dev的缩写
$ yarn add webpack-cli -D  //-D 是--save-dev的缩写
// 简化安装
$ yarn add webpack webpack-cli -D

webpack 建议在局部安装,如果安装到全局,会锁定webpack版本,多项目使用 webpack 会因为版本问题导致项目构建失败

./node_modules/.bin/webpack -v

安装完了检查版本,确认安装成功


2.2测试webpack是否安装成功(webpack 默认配置中 entry 入口是 src/index.js)


  • 创建入口文件 ./src/main.js
$ mkdir src && touch ./src/main.js

src/main.js

/*
 * @Author: your name
 * @Date: 2020-03-18 14:25:09
 * @LastEditTime: 2020-03-18 14:25:29
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \vue-cli-demo\src\main.js
 */
console.log('Hello vue-cli-demo')

这个时候到./node_modules/.bin/目录下执行webpack打包命令,我们会看到dist目录下生成对应的js文件。 这种打包方式比较麻烦,这里添加一个配置就可以更方便打包。在 package.json 文件下的 script 节点添加一项配置 "serve": "webpack",然后再删掉 dist 目录,再运行  yarn run serve就可以方便地打包了。

  • 然后在 package.json 下面加一个脚本命令
"scripts": {
    "serve": "webpack ./src/main.js --mode development",
    "dev": "webpack"(默认为src/index.js)
  },
  • 然后运行该命令
$ yarn run serve
$ yarn serve

如果在 dist 目录下生成了一个main.js文件,则表示webpack工作正常

  • 创建webpack配置文件

注意:windows不支持此类创建,具体自行百度或者手动创建或者copy

$ touch webpack.config.js

webpack.config.js配置

// 配置入口文件与输出打包文件及路径
const path = require('path')
module.exports = {
  entry: './src/index.js',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'index.js'
  } 
}
  • 配置webpack编译脚本
"scripts": {
    "dev": "webpack",
    "build": "webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  • 测试配置
$ yarn build && node ./dist/bundle.js
// 输出表示打包成功
Hello vue-cli-demo


三、配置


  • 新建一个 build 文件夹,用来存放 webpack配置相关的文件
  • 在build文件夹下新建一个webpack.base.conf.js,配置webpack的基本配置
  • 在build文件夹下新建一个webpack.dev.conf.js,配置webpack的开发环境配置
  • 在build文件夹下新建一个webpack.prod.conf.js,配置webpack的生产环境配置
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 13:50:31
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: path.resolve(__dirname, '../src/main.js')
  },
  output: {
    // 配置打包文件输出的目录
    path: path.resolve(__dirname, '../dist'),
    // 生成的 js 文件名称
    filename: 'js/[name].[hash:8].js',
    // 生成的 chunk 名称
    chunkFilename: 'js/[name].[hash:8].js',
    // 资源引用的路径
    publicPath: '/'
  }
}
  • 修改package.json 文件
"scripts": {
    "serve": "webpack ./src/main.js --config ./build/webpack.base.conf.js"
  },
  • 测试是否配置成功
$ yarn run serve 
$ yarn serve

注意:查看dist文件夹下生成js文件夹和带有hash命名的main文件表示配置成功。


3.1 loader配置


所谓loaders就是说把原本webpack不支持加载的文件或者文件内容通过loaders进行加载解析,实现应用的目的。loader是一种打包的方案,webpack默认只识别js结尾的文件,当遇到其他格式的文件后,webpack并不知道如何去处理。此时,我们可以定义一种规则,告诉webpack当他遇到某种格式的文件后,处理的方案就是所说的loader。webpack 默认只支持 js/json,可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。


3.1.1 配置 ES6/7/8 转 ES5代码

这里讲解ES6/7/8解析,原生支持js解析,但是不能解析ES6/7/8,需要babel-loader ,而babel-loader 又依赖babel。babel还可以解析jsx语法。

  • 安装babel相关依赖

ES6/7/8转换为ES5需要安装babel,babel-loader @babel/core @babel/preset-env

$ yarn add babel-loader @babel/core @babel/preset-env -S
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 14:33:55
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: path.resolve(__dirname, '../src/main.js')
  },
  output: {
    // 配置打包文件输出的目录
    path: path.resolve(__dirname, '../dist'),
    // 生成的 js 文件名称
    filename: 'js/[name].[hash:8].js',
    // 生成的 chunk 名称
    chunkFilename: 'js/[name].[hash:8].js',
    // 资源引用的路径
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      }
    ]
  }
}
  • 在项目根目录添加一个 babel.config.js 文件或者在根目录创建 .babelrc 文件,输入以下内容

babel.config.js内容

/*
 * @Author: your name
 * @Date: 2020-03-29 14:37:48
 * @LastEditTime: 2020-03-29 14:39:50
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \vue-cli-demo\babel.config.js
 */
module.exports = {
    presets: [
      [
        "@babel/preset-env"
      ]
    ]
  }

.babelrc 文件内容

{
    "presets": [
        "@babel/preset-env",
    ]
}

接着在 webpack.base.conf.js配置文件下module属性,属性内容是一个rules集合中添加如下内容

// ...
module: {
        rules: [
            {
                test: /.js$/,
                use: 'babel-loader'
            },
         ]
      }
// ...

rules集合的每个元素都是一个文件类型的配置信息,这里只有一个js文件,后面会讲到css、less及各种格式的图片等;test是一个正则,用来匹配文件后缀名;use表示此loader名称。

  • 然后执行 yarn run serve或者yarn serve 命令,可以看到 ES6代码被转成了ES5代码了
  • 注意

babel-loader只会将 ES6/7/8语法转换为ES5语法,但是对新api并不会转换。 我们可以通过安装 babel-polyfill 提供新语法的实现

安装

$ yarn add @babel/polyfill -S

修改 webpack.base.conf.js配置

/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 14:56:27
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: ["@babel/polyfill",path.resolve(__dirname, '../src/main.js')]
  },
  output: {
   ……
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      }
    ]
  }
}
  • 按需引入polyfill

配置了按需引入 polyfill 后,用到es6以上的函数,babel会自动导入相关的polyfill,这样能大大减少 打包编译后的体积

安装依赖

$ yarn add core-js@2 @babel/runtime-corejs2 -S

修改 babel-config.js

/*
 * @Author: your name
 * @Date: 2020-03-29 14:37:48
 * @LastEditTime: 2020-03-29 14:39:50
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \vue-cli-demo\babel.config.js
 */
module.exports = {
    presets: [
      [
        "@babel/preset-env",
        {
          useBuiltIns: "usage"
        }
      ]
    ]
  }


3.1.2 配置scss/sass/less/stylus转css


在没有引入loader前,引入scss/sass/less/stylus打包会报错

  • scss/sass转css配置

sass-loader, dart-sass主要是将 scss/sass 语法转为css,css-loader主要是解析 css 文件 ,style-loader 主要是将 css 解析到 html页面 的 style 上

安装相关依赖

$ yarn add sass-loader dart-sass css-loader style-loader -D

修改 webpack.base.conf.js配置

  • less转css配置

css-loader用于加载css文件并生成commonjs对象,style-loader用于将样式通过style标签插入到head

安装loader

$ yarn add style-loader css-loader less less-loader -D

修改 webpack.base.conf.js配置

// ...
module: {
        rules: [
            {
                test: /.js$/,
                use: 'babel-loader'
            },
            {
                test: /.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            },
            {
                test: /.less$/,
                use: [
                    'style-loader',
                    'css-loader',
                    'less-loader'
                ]
            },
           ]
        }
// ...

注意:这里的解析css用到了两个loader,所以use对象里是个数组,需要格外注意到loader顺序,是先写style-loader,再写css-loader,但是执行的时候是先加载css-loader,将css解析好后再将css传递给style-loader;

  • stylus转css配置


3.1.3 配置 postcss 实现自动添加css3前缀


  • 安装相关依赖
$ yarn add postcss-loader autoprefixer -D
  • 修改 webpack.base.conf.js配置
……
 module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      }
    ]
  }
  ……
  • 在项目根目录下新建一个 postcss.config.js
/*
 * @Author: your name
 * @Date: 2020-03-29 15:39:27
 * @LastEditTime: 2020-03-29 15:39:43
 * @LastEditors: your name
 * @Description: In User Settings Edit
 * @FilePath: \vue-cli-demo\postcss.config.js
 */
module.exports = {
    plugins: {
        autoprefixer: {}
    }
}


3.1.4 配置 webpack 打包 图片、媒体、字体等文件


ebpack 打包 图片、媒体、字体等文件在webpack中的打包步骤跟上面类似,只不过loader不同。

  • 安装依赖

file-loader 解析文件url,并将文件复制到输出的目录中 url-loader 功能与 file-loader 类似,如果文件小于限制的大小。则会返回 base64 编码,否则使用 file-loader 将文件复制到输出的目录中,url-loader直接内置了file-loader,是对它的再封装,在配置文件里可以直接去掉file,用url替换。

$ yarn add file-loader url-loader -D
  • 修改 webpack.base.conf.js配置 添加 rules 配置,分别对 图片,媒体,字体文件进行配置
//..
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      {
        test: /\.(jpe?g|png|gif|jpeg)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                    name: 'img/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'media/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'fonts/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
    ]
  },
  //..

注意:limit是指图片大小上限,单位是字节,如果图片大小小于这个值,就会被打包为base64格式,否则就仍是图片。


3.1.5 webpack 编译 .vue 文件


浏览器只能识别html/js/css,对于.vue文件直接引入,浏览器会报错,这个时候webpack的vue-loader就派上了用场

  • 安装需要的依赖文件
$ yarn add vue-loader vue-template-compiler cache-loader thread-loader -D
$ yarn add vue -S
  • vue-loader 用于解析.vue文件
  • vue-template-compiler 用于编译模板
  • cache-loader 用于缓存loader编译的结果
  • thread-loader 使用 worker 池来运行loader,每个 worker 都是一个 node.js 进程。
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 22:20:37
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
// 引入生成页面插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入webpack
const webpack = require('webpack')
// 引入vueloader编译器
const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: ["@babel/polyfill",path.resolve(__dirname, '../src/main.js')]
  },
  output: {
    // 配置打包文件输出的目录
    path: path.resolve(__dirname, '../dist'),
    // 生成的 js 文件名称
    filename: 'js/[name].[hash:8].js',
    // 生成的 chunk 名称
    chunkFilename: 'js/[name].[hash:8].js',
    // 资源引用的路径
    publicPath: '/'
  },
  resolve: {
    alias: {
      vue$: 'vue/dist/vue.runtime.esm.js'
    },
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'cache-loader'
          },
          {
            loader: 'thread-loader'
          },
          {
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                preserveWhitespace: false
              },
            }
          }
        ]
      },
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'cache-loader'
          },
          {
            loader: 'thread-loader'
          },
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      },
      {
        test: /\.(jpe?g|png|gif|jpeg)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                    name: 'img/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'media/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 4096,
              fallback: {
                loader: 'file-loader',
                options: {
                  name: 'fonts/[name].[hash:8].[ext]'
                }
              }
            }
          }
        ]
      },
    ]
  },
  devServer: {
  //……
  },
  plugins: [
    //……
    new VueLoaderPlugin()
  ]
}


3.2 插件配置(plugins)


插件是 webpack 的支柱功能。webpack 自身也是构建在 webpack 配置中用到的相同的插件系统之上。插件目的在于解决 loader 无法实现的其他事。webpack 有着丰富的插件接口(rich plugin interface)。webpack 自身的多数功能都使用这个插件接口。这个插件接口使 webpack 变得极其灵活。


3.2.1 插件html-webpack-plugin(必须)


使用 html-webpack-plugin来自动创建html页面,并将打包的bundle.js并自动引入

  • 安装依赖
$ npm install html-webpack-plugin --save-dev
$ yarn add html-webpack-plugin -D
  • 新建一个 public/index.html 页面
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> -->
    <title>vue-cli-demo</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but vue-admin doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 16:03:52
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
// 引入生成页面插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: ["@babel/polyfill",path.resolve(__dirname, '../src/main.js')]
  },
  output: {
   ……
  },
  module: {
  ……
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html')
    })
  ]
}


3.2.2 配置 clean-webpack-plugin


每次部署自动清空 dist 目录

  • 安装依赖
$ npm install clean-webpack-plugin --save-dev
$ yarn add clean-webpack-plugin -D
复制代码
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 16:03:52
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
const htmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
plugins: [
    // 复制一个 html 并将最后打包好的资源在 html 中引入
    new htmlWebpackPlugin({
        // 页面title 需要搭配 ejs 使用
        title: "讯曌科技",
        // html 模板路径
        template: "./index.html",
        // 输出文件名称
        filename: "index.html",
        minify: {
            // 压缩HTML⽂件
            removeComments: true, // 移除HTML中的注释
            collapseWhitespace: true, // 删除空⽩符与换⾏符
            minifyCSS: true // 压缩内联css
        }
    }),
    // 每次部署时清空 dist 目录
    new CleanWebpackPlugin()
],


3.2.3 配置 devServer 热更新功能


通过代码的热更新功能,我们可以实现不刷新页面的情况下,更新我们的页面,通过配置 devServer 和 HotModuleReplacementPlugin 插件来实现热更新

  • 安装依赖
$ yarn add webpack-dev-server -D
  • 修改 webpack.base.conf.js配置
/*
 * @Author: your name
 * @Date: 2020-03-18 09:54:47
 * @LastEditTime: 2020-03-29 16:18:06
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \doc_exchange_front_end\build\webpack.base.conf.js
 */
'use strict'
const path = require('path')
// 引入生成页面插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 引入webpack
const webpack = require('webpack')
module.exports = {
  // 打包模式
  mode: 'development',  
  entry: {
    // 配置入口文件
    main: ["@babel/polyfill",path.resolve(__dirname, '../src/main.js')]
  },
  output: {
    // 配置打包文件输出的目录
    path: path.resolve(__dirname, '../dist'),
    // 生成的 js 文件名称
    filename: 'js/[name].[hash:8].js',
    // 生成的 chunk 名称
    chunkFilename: 'js/[name].[hash:8].js',
    // 资源引用的路径
    publicPath: '/'
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ]
      },
      {
        test: /\.(scss|sass)$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 2
            }
          },
          {
            loader: 'sass-loader',
            options: {
              implementation: require('dart-sass')
            }
          },
          {
            loader: 'postcss-loader'
          }
        ]
      }
    ]
  },
  devServer: {
    hot: true,
    port: 3000,
    contentBase: './dist',
    open: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html')
    }),
    new webpack.NamedModulesPlugin(),
    new webpack.HotModuleReplacementPlugin(),
  ]
}


四、入口起点(entry points)



五、输出(output)



六、模式(mode)




目录
相关文章
|
20天前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
19天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
19天前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
24天前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
29天前
|
缓存 JavaScript 前端开发
《基础篇第4章:vue2基础》:使用vue脚手架创建项目
《基础篇第4章:vue2基础》:使用vue脚手架创建项目
65 3
|
1月前
|
前端开发 JavaScript 安全
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
在vue前端开发中基于refreshToken和axios拦截器实现token的无感刷新
88 4
|
19天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】 React与Vue:前端框架的巅峰对决与选择策略
|
26天前
|
前端开发 JavaScript API
2025年前端框架是该选vue还是react?有了大模型-例如通义灵码辅助编码,就不用纠结了!vue用的多选react,react用的多选vue
本文比较了Vue和React两大前端框架,从状态管理、数据流、依赖注入、组件管理等方面进行了详细对比。当前版本和下载量数据显示React更为流行,但Vue在国内用户量增长迅速。Vue 3通过组合式API提供了更灵活的状态管理和组件逻辑复用,适合中小型项目;React则更适合大型项目和复杂交互逻辑。文章还给出了选型建议,强调了多框架学习的重要性,认为技术问题已不再是选型的关键,熟悉各框架的最佳实践更为重要。
|
1月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
130 2
|
1月前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
38 0