手動實現一個vue cli
- 手動實現一個vue cli
- 1. 思考準備
- 2. 我們組織原始碼將會放在名為src的目錄,webpack 打包需要一個入口檔案,我們取作 main.js
- 3. 先預想以下會用到哪些基本依賴,第一個容易想到的是Vue, 然後是我們假設專案需要使用elementUI , 還有axios ,先就這些:
- 4. 我們的目標是要把src 中的從main.js 開始去編譯-打包,到dist 資料夾中去, 所以我們需要配置檔案,進行配置。 所以建立webpack 的配置檔案, webpack.config.js
- 5. 編寫配置:
- 6. 編寫入口檔案 main.js
- 7. 準備跑起來專案,建立一個快捷指令碼去呼叫非全域性webpack 命令
- 8. 啟動專案
- 9. 做一些增強,引入路由
- 10. 進一步增強,引入webpack 開發伺服器
- 11. 優化配置,自動開啟瀏覽器
- 12. 更多
手動實現一個vue cli
1. 思考準備
最一開始:建立一個web專案,所以需要一個html 檔案,又是一個Vue 專案,所以需要一個div,並指明一個id.
我們使用webpack 打包後的檔案,需要被引入,bundle.js, 應該把它放在dist (分發)資料夾。
----> 指明id 的 div 的html 檔案
----> dist 資料夾
目前結構為:
.
└── dist
└── index.html
index.html 內容為:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>VueStarter</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
2. 我們組織原始碼將會放在名為src的目錄,webpack 打包需要一個入口檔案,我們取作 main.js
.
├── dist
│ └── index.html
└── src
└── main.js
3. 先預想以下會用到哪些基本依賴,第一個容易想到的是Vue, 然後是我們假設專案需要使用elementUI , 還有axios ,先就這些:
npm i vue element-ui axios
最終我們需要的核心檔案是打包後的bundle.js , 接下來需要用到的核心是webpack , 所以安裝 webpack
以及想到, 需要引入vue 的程式碼 vue-loader 以及 .vue 檔案的解析依賴 vue-template-compiler
樣式sass-loader 以及sass 本體
處理後的css 檔案需要通過css-loader 載入,然後被style 標籤解析,需要用到 style-loader
還需要babel 來處理es6的新語法,所以需要安裝
babel babel-loader @babel/core babel 的預設配置 @babel/preset-env(env 代表相容最新的語法)
# -D 指的是開發環境
npm i -D webpack webpack-cli vue-loader vue-template-compiler sass-loader sass css-loader style-loader babel-loader @babel/core @babel/preset-env
4. 我們的目標是要把src 中的從main.js 開始去編譯-打包,到dist 資料夾中去, 所以我們需要配置檔案,進行配置。 所以建立webpack 的配置檔案, webpack.config.js
發現沒有自動生成 package.json 檔案, 命令 npm init 手動生成, 將入口檔案指定為main.js
. ├── README.md# 手動生成的 ├── dist ├── node_modules ├── package-lock.json ├── package.json ├── src └── webpack.config.js
5. 編寫配置:
基本結構熟悉:
module.exports = {
entry:'',//入口檔案
output:{//出口檔案,
path:'',
filename:'',
},
module:{//webpack 中一切皆模組
rules:[
{ test:/\.vue$/,use:'vue-loader'},
....
]
},
plugins:[//外掛用於增強webpack
new PluginsA(),//每一個外掛就是一個例項
new PluginsB(),
...
]
}
開始填充內容:
const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
entry: "./src/main.js", //入口檔案 絕對路徑 / 相對路徑
output: {
//出口檔案,
path: path.resolve(__dirname, "dist") + "", //絕對路徑 __dirname 是node "當前所在路徑pwd" , 由於window 的目錄分隔符是 '\', 而類nix是 '/', 為了保持靈活性,使用了node 內建的path 物件方法,將自動將當前系統目錄分隔符和目錄名拼接
filename: "bundle.js",
},
module: {
//webpack 中一切皆模組
rules: [
{ test: /\.vue$/, use: "vue-loader" },
/**
* 處理.vue 檔案的載入, 寫法可以指定
* 單個依賴 - String,
* 單個帶配置的依賴 - {}
* 多個不帶配置的依賴 - []String ,
* 多個帶配置的依賴 []Object
* { test: /\.vue$/, use: [{loader:'vue-loader',options:{}},{}...] },
*/
{
test: /\.s[ca]ss$/,
use: ["style-loader", "css-loader", "scss-loader"],
}, //要注意順序,依次從後往前解析
{
test: /\.m?js$/, //.msj 是es6 的模組化js 檔案
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
//圖片處理
// test: /\.(png|jpe?g|gif|svg|webp)$/,use: { laoder: "file-loader", options: { esModule: false } },//老語法
test: /\.(png|jpe?g|gif|svg|webp)$/,
type: "asset/resource",
},
],
},
plugins: [
//外掛用於增強模組
// vue-template-compiler 的作用是解析.vue 檔案內部時,遇到js 塊和css 塊時的處理方式,複用我們上面定義的規則
new VueLoaderPlugin(),
],
}
6. 編寫入口檔案 main.js
import Vue from "vue";
import App from "./App.vue";
new Vue({
el: "#app",
render: (h) => h(App), //將App 依賴通過渲染函式渲染成DOM 節點,掛載到 #app 節點下
});
<!--App.vue-->
<template>
<div>hello vue starter</div>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped></style>
7. 準備跑起來專案,建立一個快捷指令碼去呼叫非全域性webpack 命令
#package.json
"scripts": {
"serve": "webpack --mode=development --watch",
"build": "webpack --mode=production"
},
在package.json 檔案中指定的 script 指令碼會自動去執行node_modules/bin 下的指令碼, mode 選項指定啟動模式:
- production : 生成環境,壓縮程式碼,無錯誤提示
- development : 開發環境,不壓縮程式碼
watch : 檢測檔案變化,自動重新編譯打包
8. 啟動專案
cmd 執行命令 npm run serve
dist 目錄下生成了 bundle.js 檔案,
此時開啟dist 目錄下的index.html 檔案。將會看到App.vue 中寫的內容:
這說明初步成功了。
9. 做一些增強,引入路由
安裝依賴
npm i vue-router
# -S 是預設引數
建立 /router/index.js 並編輯:
import VueRouter from "vue-router";
import Home from "../pages/Home.vue";
import Vue from "vue";
Vue.use(VueRouter);
const router = new VueRouter({
routes: [
{
path: "",
component: Home,
},
{
path: "/me",
component: () => import("../pages/About.vue"),
},
],
});
export default router;
main.js 中引入:
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
new Vue({
el: "#app",
router,
render: (h) => h(App), //將App 依賴通過渲染函式渲染成DOM 節點,掛載到 #app 節點下
});
App.vue 註冊 <router-view>
標籤:
<template>
<div>
<span>hello vue starter</span>
<div><button @click="$router.push('/')">HomePage</button></div>
<div><button @click="$router.push('/me')">About Me</button></div>
<router-view></router-view>
</div>
</template>
<script>
export default {};
</script>
<style lang="scss" scoped></style>
啟動程式 npm run serve
10. 進一步增強,引入webpack 開發伺服器
```bash
npm i -D webpack-dev-server
```
修改啟動指令碼:
pacakge.json
```json
"serve": "webpack --mode=development --watch",
```
修改為:
```json
"serve": "webpack serve --mode=development",
```
> webpack -dev-server 提供了子命令serve 並會自動watch
配置webpack.config.js
啟動專案:
```bash
npm run serve
```
![image-20211102000024219](https://img2020.cnblogs.com/blog/1735896/202111/1735896-20211102002121545-385713942.png)
![image-20211102000046376](https://img2020.cnblogs.com/blog/1735896/202111/1735896-20211102002121262-958672201.png)
11. 優化配置,自動開啟瀏覽器
webpack.config.js:
```json
devServer: {
static: "./dist",
open:true
},
```
12. 更多
```json
const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
entry: "./src/main.js", //入口檔案 絕對路徑 / 相對路徑
output: {
//出口檔案,
path: path.resolve(__dirname, "dist") + "", //絕對路徑 __dirname 是node "當前所在路徑pwd" , 由於window 的目錄分隔符是 '\', 而類nix是 '/', 為了保持靈活性,使用了node 內建的path 物件方法,將自動將當前系統目錄分隔符和目錄名拼接
filename: "bundle.js",
},
module: {
//webpack 中一切皆模組
rules: [
{ test: /\.vue$/, use: "vue-loader" },
/**
* 處理.vue 檔案的載入, 寫法可以指定
* 單個依賴 - String,
* 單個帶配置的依賴 - {}
* 多個不帶配置的依賴 - []String ,
* 多個帶配置的依賴 []Object
* { test: /\.vue$/, use: [{loader:'vue-loader',options:{}},{}...] },
*/
{
test: /\.s[ca]ss$/,
use: ["style-loader", "css-loader", "scss-loader"],
}, //要注意順序,依次從後往前解析
{
test: /\.m?js$/, //.msj 是es6 的模組化js 檔案
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
},
},
},
{
//圖片處理
// test: /\.(png|jpe?g|gif|svg|webp)$/,use: { laoder: "file-loader", options: { esModule: false } },//老語法
test: /\.(png|jpe?g|gif|svg|webp)$/,
type: "asset/resource",
},
],
},
plugins: [
//外掛用於增強模組
// vue-template-compiler 的作用是解析.vue 檔案內部時,遇到js 塊和css 塊時的處理方式,複用我們上面定義的規則
new VueLoaderPlugin(),
],
devServer: {
static: "./dist",
open: true,
host: "local-ip", //啟動地址為區域網ipv4 地址
port: 3333, //手動指定地址,
onListening(devServer) {
//命令列自定義輸出
console.log(
"Listening :http://",
devServer.server.address().address,
":",
devServer.server.address().port,
);
},
},
};
```