使用webpack搭建一个简单的vue脚手架

生成package.json

npm init

安装依赖

npm i webpack vue vue-loader css-loader vue-template-compiler

新建文件夹src,创建文件app.vue

<template>
    <div class="text">{{text}}</div>
</template>

<script>
export default {
    data(){
        return{
            text:'abc'
        }
    }
}
</script>

<style scoped>
    .text{
        color:red;
    }
</style>

创建webpack.config.js (帮助打包前端资源)

// 打包前端资源
const path = require('path')
const VueLoaderPlugin = require("vue-loader/lib/plugin");

module.exports = {
  entry: path.join(__dirname, "src/index.js"),
  output: {
    filename: "app.js",
    path: path.join(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        loader: "vue-loader",
      },
      {
        test: /\.css$/,
        loader: "css-loader",
      }
    ],
  },
  plugins: [
    // 请确保引入这个插件!
    new VueLoaderPlugin(),
  ],
};

在src目录中创建index.js (入口文件)

// 入口文件
import Vue from 'vue'
import App from './app.vue'

const root=document.createElement("div")
document.body.appendChild(root)

new Vue({
    render:(h)=>h(App)
}).$mount(root)

在package.json中的scripts里添加一个命令

...
"build": "webpack --config webpack.config.js"
...

执行打包

npm run build

打包后会在dist目录生成打包好后的文件。

webpack插件 - plugin

plugin是用于扩展webpack的功能,各种各样的plugin几乎可以让webpack做任何与构建相关的事情。
plugin的配置很简单,plugins配置项接收一个数组,数组里的每一项都是一个要使用的plugin的实例,plugin需要的参数通过构造函数传入。

举个例子

const HtmlWebpackPlugin = require('html-webpack-plugin')
  plugins: [
    new HtmlWebpackPlugin({ // 打包输出HTML
      title: 'Hello World app',
      minify: { // 压缩HTML文件
        removeComments: true, // 移除HTML中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        minifyCSS: true// 压缩内联css
      },
      filename: 'index.html',
      template: 'index.html'
    }),
  ]

使用plugin的难点在于plugin本身的配置项,而不是如何在webpack中引入plugin,几乎所有webpack无法直接实现的功能,都能找到开源的plugin去解决,我们要做的就是去找更据自己的需要找出相应的plugin。

HTMLPlugin

虽然现在可以打包了,但是只生成了js文件,并没有生成html文件,我们需要引入一个插件 HTMLPlugin。

在webpack.config.js中加入以下代码:

const HTMLPlugin = require('html-webpack-plugin');
...
// 在插件列表中声明引用了HTMLPlugin插件
plugins: [
    new VueLoaderPlugin(),
    new HTMLPlugin({
        title: 'Hello World app',
    }) // 处理html模版
],
...

现在执行npm run build可以打包出index.html了,双击这个文件是可以直接在浏览器中运行的。

了解html-webpack-plugin的更多内容,详见 HTMLPlugin.md

webpack-dev-server

每次打包一次再运行实在是太麻烦了,我们希望能够在一个服务端口上运行这个项目,并且代码有改动时能够热更新,这个时候就需要webpack-dev-server。

安装webpack-dev-server

npm install webpack-dev-server --save

修改 webpack.config.js

// 打包前端资源
const path = require('path')
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const HTMLPlugin = require('html-webpack-plugin');
const isDev = process.env.NODE_ENV === 'development';  // 判断当前环境是否为开发环境

const config = {
  entry: path.join(__dirname, "src/index.js"),
  output: {
    filename: "app.js",
    path: path.join(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        loader: "vue-loader",
      },
      {
        test: /\.css$/,
        loader: "css-loader",
      }
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new HTMLPlugin({
      title: '使用webpack搭建一个vue应用'
    })
  ],
};

if(isDev) {
  Object.assign(config, {
    // 调试代码时可以看到自己原本的代码,而不是编译后的
    devtool: '#cheap-module-eval-source-map',
    devServer: {
      port: 8000,
      host: '0.0.0.0',
      overlay: {
          errors: true // 将webpack编译的错误显示在网页上面
      },
      open: true, // 在启用webpack-dev-server时,自动打开浏览器
      hot: true 
    }
  })
}

module.exports = config;

package.json中的scripts里添加一个命令

...
"scripts": {
    ...
    "dev": "webpack-dev-server --config webpack.config.js"
}
...

执行命令 npm run dev 就会启动一个8080端口,就可以在浏览器http://localhost:8080 访问到这个项目了。

图片的加载

目前的配置是不支持加载图片的,接下来我们让它支持加载图片。

使用file-loader处理文件的导入

npm install file-loader --save-dev

在webpack.config.js中修改

module: {
    rules: [
    	...
        {
            test: /\.(gif|jpg|jpeg|png|svg)$/, // 处理图片文件
            use: {
              loader: 'file-loader',
              options: {
                name: '[name]_[hash].[ext]',
              }
            }
        }
        ...
      ]
}

经测试使用file-loader仅支持 import img from "./assets/logo.jpg";background: url('./assets/logo.jpg'); 的引用,并不能支持 <img src="./assets/logo.jpg" >,会将图片地址解析成[object module] ,查了资料后发现:

默认情况下,file-loader生成使用ES模块语法的JS模块。在某些情况下,使用ES模块是有益的,比如在模块连接和树抖动的情况下。

简而言之就是file-loader新版本默认使用了esModule语法,造成了引用图片文件时的方式和以前的版本不一样,通过查看其仓库的release会发现:在v4.3.0版本就引入这一新特性。

解决方法是在webpack的file-loader配置项里,设置esModule为false

module: {
    rules: [
    	...
        {
            test: /\.(gif|jpg|jpeg|png|svg)$/, // 处理图片文件
            use: {
              loader: 'file-loader',
              options: {
                name: '[name]_[hash].[ext]',
                esModule: false  
              }
            }
        }
       ...
      ]
}

除了file-loader还可以使用url-loader,url-loader是在file-loader的基础上做了一层封装,能够让较小的图片打包成base64

npm install url-loader --save-dev
// 将file-loader换成url-loader,并加入	limit 属性
use: {
    loader: 'url-loader',
    options: {
        name: '[name]_[hash].[ext]',
        esModule: false,
        limit: 4096088  // 表示小于这个大小的图片的地址都会转化成base64
  	}
}

支持less

less是css的预处理语言,它扩展了css语言,下面让我们的webpack支持less

安装less相关依赖

npm i less-loader less --save-dev

在webpack.config.js中加入less的对应规则

{
  test: /\.less$/,
    use: [
      {
        loader: 'style-loader'
      },
      {
        loader: 'css-loader'
      },
      {
        loader: 'less-loader'
      }
    ]
}

至此一个简单的vue脚手架就搭建好啦,如果你想更完善一点,后续可以添加更多的功能。

支持typescript

typescript是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程

安装依赖

npm install typescript ts-loader --save-dev

将入口文件文件名index.js改成index.ts

修改webpack配置

...
// 入口文件地址改一下
entry: path.join(__dirname, "src/index.ts"),
...

// 加入对ts文件的处理规则
...
{
  test: /\.tsx?$/,
  loader: 'ts-loader',
  exclude: /node_modules/,
  options: {
  	appendTsSuffixTo: [/\.vue$/]
  }
}
...

创建typescript配置文件,tsconfig.json,这里的配置可以根据实际要求进行配置

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ]
}

添加对vue的声明,在src目录下创建文件shims-vue.d.ts

declare module "*.vue" {
  import Vue from "vue"
  export default Vue
}

需要注意的是如果在Vue原型当中添加了属性,也需要添加对应的声明,但是由于vue-router和vuex这种是作为Vue插件来使用的 (也就是按Vue.use(Router)这种方式来使用),并且都已经支持TypeScript,所以并不需要单独来编写声明了。但是像axios这种并不是按Vue插件使用,需要用下面的方式添加到Vue原型当中

Vue.prototype.$http = axios

那么使用了TypeScript之后,就需要对该属性进行声明
否则ts编译的过程就会认为该属性不存在

在src目录下创建index.d.ts

import { AxiosInstance } from 'axios'

declare module 'vue/types/vue' {
  interface Vue {
    $http: AxiosInstance
  }
}

vue-class-component和vue-property-decorator

vue-class-component 是官方推出的vue对typescript支持的装饰器(库),可以将Vue中的组件用类的方式编写,vue-property-decoratorvue-class-component 的超集,下面我们来学习一下vue-property-decorator

安装依赖包

npm install vue-property-decorator vue-class-component --save

组件就可以这么写了

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
@Component({
  filters: {
    toFixed: (num: number, fix: number = 2) => {
      return num.toFixed(fix)
    }
  }
})
export default class MyComponent extends Vue {
  public list: number[] = [0, 1, 2, 3, 4]
  get evenList() {
    return this.list.filter((item: number) => item % 2 === 0)
  }
}
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值