Skip to content

从零开始做Vue前端架构(1)基本webpack配置 #10

Description

@CodeLittlePrince

前言

想想也已经做过不少架构的项目了,有基于vue,基于react,基于thinkPHP,基于laravel的。

做多了,也就对现有的架构有各种想法,有好的,有坏的,总之,用起来还是不爽。vue-cli虽然可以很快地构建并使用,尤其是vue-cli v3.0,把webpack都封进@vue/cli的sdk里了,用起来更加干净、简洁。

但是,对于爱折腾的我们,好吧,开个玩笑。重来,但是,对于页面的优化,还有项目的架构,我们不得不做多多少少的修改。

好了,介绍完毕,接下来,我就从零开始,一步一步建起前后端完全分离的前端架构了。

步骤

由于要介绍的很多,全写在一篇里,有些太长了。

所以,我会分为:

  1. 创建开发环境下的webpack配置文件

  2. 配置eslint、babel、postcss

  3. 创建项目文件、目录架构

  4. 通过koa实现本地数据接口模拟

  5. 创建发布环境下的webpack配置文件

  6. 创建测试环境下的webpack配置文件、以及测试用例 (TODO)

  7. 自动初始化构建项目(TODO)

这七篇来分别介绍。

开发

一、初始化项目

  1. 创建项目文件夹
    我们就叫vue-construct

  2. 初始化git
    git init

  3. 初始化npm
    npm init

  4. 创建项目文件
    为了能让webpack跑起来,而不是一口气只讲配置而不运行一下,那样未免有些空洞,所以我们先创建一点项目文件和目录。
    在这之前我们先安装两个包:vue、vue-router, npm i -S vue vue-router
    我们将项目代码相关文件都放在名为app的文件夹下。我先都创建完,然后一个个介绍。

├── app
│ ├── app.vue
│ ├── common
│ │ ├── img
│ │ ├── js
│ │ └── scss
│ ├── index.html
│ ├── index.js
│ ├── router
│ │ └── index.js
│ └── views
│ └── home
│ └── index.vue
├── .gitignore
├── package-lock.json
├── package.json
└── webpack.config.js

node_modules的话就忽略了。

文件/文件夹用途
app.vue作为vue的主文件
common里面放公共的代码
index.html页面模板文件
index.js项目主入口文件
router放vue对应的router文件
views放视图文件
.gitignore忽略node_module

咱们暂且不关系这些文件里的具体代码是什么,等webpack配置完再说。

二、配置webpack.config.js

  1. 安装一系列的包:
    为了webpack的运行,需要安装
webpack
webpack-dev-server

为了处理vue单页文件,安装:

vue-loader

为了处理scss文件并从js中抽离,安装:

node-sass
style-loader
css-loader
sass-loader
vue-style-loader
postcss
postcss-loader
autoprefixer
extract-text-webpack-plugin

为了处理图片和字体文件,安装:

file-loader
url-loader

为了支持高级语法-babel,安装:

babel
babel-loader
babel-plugin-syntax-dynamic-import
babel-plugin-transform-object-rest-spread
babel-polyfill
babel-preset-env

为了验证代码格式-eslint,安装:

eslint
eslint-loader
eslint-plugin-html
babel-eslint
  1. 配置webpack.config.js文件
constwebpack=require('webpack')constpath=require('path')constHtmlWebpackPlugin=require('html-webpack-plugin')constFriendlyErrorsPlugin=require('friendly-errors-webpack-plugin')// 为了抽离出两份CSS,创建两份ExtractTextPlugin// base作为基础的css,基本不变,所以,可以抽离出来充分利用浏览器缓存// app作为迭代的css,会经常改变constisProduction=process.env.NODE_ENV==='production'constExtractTextPlugin=require('extract-text-webpack-plugin')constextractBaseCSS=newExtractTextPlugin({filename:'static/css/base.[chunkhash:8].css',allChunks: true,disable: !isProduction// 开发环境下不抽离css})constextractAppCSS=newExtractTextPlugin({filename:'static/css/app.[chunkhash:8].css',allChunks: true,disable: !isProduction// 开发环境下不抽离css})// 减少路径书写functionresolve(dir){returnpath.join(__dirname,dir)}// 网站图标配置constfavicon=resolve('favicon.ico')// __dirname: 总是返回被执行的 js 所在文件夹的绝对路径// __filename: 总是返回被执行的 js 的绝对路径// process.cwd(): 总是返回运行 node 命令时所在的文件夹的绝对路径constconfig={// sourcemap 模式devtool: 'cheap-module-eval-source-map',// 入口entry: {app: resolve('app/index.js')},// 输出output: {path: resolve('dev'),filename: 'index.bundle.js'},resolve: {// 扩展名,比如import 'app.vue',扩展后只需要写成import 'app'就可以了extensions: ['.js','.vue','.scss','.css'],// 取路径别名,方便在业务代码中importalias: {api: resolve('app/api/'),common: resolve('app/common/'),views: resolve('app/views/'),components: resolve('app/components/'),componentsBase: resolve('app/componentsBase/'),directives: resolve('app/directives/'),filters: resolve('app/filters/'),mixins: resolve('app/mixins/')}},// loaders处理module: {rules: [{test: /\.js$/,include: [resolve('app')],loader: ['babel-loader','eslint-loader']},{test: /\.vue$/,exclude: /node_modules/,loader: 'vue-loader',options: {extractCSS: true,loaders: {scss: extractAppCSS.extract({fallback: 'vue-style-loader',use: [{loader: 'css-loader',options: {sourceMap: true}},{loader: 'postcss-loader',options: {sourceMap: true}},{loader: 'sass-loader',options: {sourceMap: true}}]})}}},{test: /\.(css|scss)$/,use: extractBaseCSS.extract({fallback: 'style-loader',use: [{loader: 'css-loader',options: {sourceMap: true}},{loader: 'postcss-loader',options: {sourceMap: true}},{loader: 'sass-loader',options: {sourceMap: true}}]})},{test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/,loader: 'url-loader',options: {limit: 8192,name: isProduction
? 'static/img/[name].[hash:8].[ext]'
: 'static/img/[name].[ext]'}},{test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,loader: 'url-loader',options: {limit: 8192,name: isProduction
? 'static/font/[name].[hash:8].[ext]'
: 'static/font/[name].[ext]'}}]},plugins: [// html 模板插件newHtmlWebpackPlugin({
favicon,filename: 'index.html',template: resolve('app/index.html')}),// 抽离出cssextractBaseCSS,extractAppCSS,// 热替换插件newwebpack.HotModuleReplacementPlugin(),// 更友好地输出错误信息newFriendlyErrorsPlugin()],devServer: {proxy: {// 凡是 `/api` 开头的 http 请求,都会被代理到 localhost:7777 上,由 koa 提供 mock 数据。// koa 代码在 ./mock 目录中,启动命令为 npm run mock。'/api': {target: 'http://localhost:7777',// 如果说联调了,将地址换成后端环境的地址就哦了secure: false}},host: '0.0.0.0',port: '9999',disableHostCheck: true,// 为了手机可以访问contentBase: resolve('dev'),// 本地服务器所加载的页面所在的目录// historyApiFallback: true, // 为了SPA应用服务inline: true,//实时刷新hot: true// 使用热加载插件 HotModuleReplacementPlugin}}module.exports={config: config,extractBaseCSS: extractBaseCSS,extractAppCSS: extractAppCSS}

总结

这一篇主要就做了三件事:

  1. 创建简单的项目结构
  2. 安装了这篇,以及之后要用到npm包
  3. 配置开发环境的Webpack

下一篇我们将配置eslint、babel、postcss - 从零开始做Vue前端架构(2)

项目完整代码

Vue前端架构-by 子咻

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions