最近在看webpack4,深感知識淺薄,這兩天也一直在思考cli的配置,藉助一些別人的實踐,嘗試本身搭建vue的項目,這裏使用webpack4版本,以前我在網上查找別人的vue項目搭建,可是都是webpack3的,因此寫了本文,若是有錯誤,或者有什麼問題,請大佬們指出javascript
關於webpack的本文不會多說,請看webpack文檔css
關於本文的github地址vue-MYCLIhtml
完成了基本的js vue css 的配置 基礎版本vue
安裝了vue-router vuex less eslint,webpack配置已經調整完畢,基本可使用 完整版本java
npm init
安裝webpack4node
npm install webpack webpack-cli --save-dev
在開始以前先實驗一下環境react
根目錄新建文件 index.htmlwebpack
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue</title> </head> <body> <script src="./src/mian.js"></script> </body> </html>
根目錄新建文件 src/main.jsgit
console.log("我是main");
根目錄新建文件webpack.config.jses6
const path = require('path') module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, dist), filename: 'index.js' } }
打包js文件
npx webpack --config webpack.config.js
會看到一些報錯,只要構建成功就ok
這裏說明環境是沒有問題的
開始安裝vue-loader吧
npm i webpack vue vue-loader -D //-D就是--save-dev
安裝完成後看輸出
提示安裝的依賴要安裝
npm install webpack css-loader -D
安裝完畢後新建src/app.vue
<template> <div> 你好 {{ data }} </div> </template> <script> export default { data(){ return { data: "Vue" } } } </script> <style scoped> </style>
.vue文件是沒法直接運行的,須要在webpack裏面配置loader
這裏參照某課的老師的方法,html用webpack生成(後面說明)
在根目錄新建index.js 刪除index.html
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)
改寫webpack.config.js
const path = require('path') module.exports = { entry: path.resolve(__dirname, 'src/index.js'), //關於path模塊能夠看看阮一峯的教程 http://javascript.ruanyifeng.com/nodejs/path.html#toc0 output: { path: path.resolve(__dirname, 'dist'), filename: 'index.js' }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader' }] } }
在package裏面添加腳本
"build": "webpack --config webpack.config.js"
控制檯運行
npm run build
不出意外會報錯
這裏有2個問題,一個是沒有指定mode 一個是沒有引用vue的插件
咱們須要改寫webpack.config.js,在config裏面加一行
mode: 'production', //暫時指定爲生產環境
再次運行npm run build
會報錯,須要安裝一個包
這個報錯,本來在vue-loader就有提示,不知道爲何如今沒有,運行以前報錯
Error: [vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options
安裝vue-template-compiler
npm install vue-template-compiler -D
再再次運行npm run build
假如按步驟來不除意外這裏能夠打包成功了~~~~
咱們須要驗證打包文件時候是否正確,因此這裏使用插件HtmlWebpackPlugin,幫咱們自動建立html文件,而且在後續的hash文件名上頗有用,具體能夠看官方介紹
npm install html-webpack-plugin -D
改webpack.config.js代碼
const path = require('path') const { VueLoaderPlugin } = require('vue-loader') var HtmlWebpackPlugin = require('html-webpack-plugin'); //引入插件 module.exports = { mode: 'production', //暫時指定爲生產環境 entry: path.resolve(__dirname, 'src/index.js'), //關於path模塊能夠看看阮一峯的教程 http://javascript.ruanyifeng.com/nodejs/path.html#toc0 output: { path: path.resolve(__dirname, 'dist'), filename: 'index.js' }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader' }] }, plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin() ] }
npm run build
打包一下,dist文件夾下面會有兩個文件
打包Vue程序完成~~~~
至此完成了最基本的webpack配置
接下來咱們要完成的的配置開發環境
關於開發環境以及生成環境,webpack是須要區分的,根據文檔模塊,我決定在命令裏面指定模式,相應的就將開發環境以及生成環境分開,
這裏我使用的是提起基本的webpack配置使用webpack-merge
這個包來拼接咱們webpack配置
npm i webpack-merge -D
修改配置文件
將各各環境的代碼區分開,webpack的結構是這樣的
webpack.config.base.js
const path = require('path') const config = { entry: path.resolve(__dirname, '../src/index.js'), output: { path: path.resolve(__dirname, 'dist'), filename: 'index.js' }, module: { rules: [{ test: /\.vue$/, loader: 'vue-loader' }] } } module.exports = config
webpack.config.build.js
const { VueLoaderPlugin } = require('vue-loader') const HtmlWebpackPlugin = require('html-webpack-plugin') const merge = require('webpack-merge') const baseConfig = require('./webpack.config.base') const config = merge(baseConfig ,{ plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin() ] }) module.exports = config
這裏配置開發環境就是重頭戲了,咱們使用webpack-dev-server
webpack-dev-server是一個小型的Node.js Express
服務器,代碼都跑在內存裏面
安裝webpack-dev-server
npm install webpack-dev-server -D
webpack.config.dev.js
const webpack = require('webpack') const merge = require('webpack-merge') const baseConfig = require('./webpack.config.base') const { VueLoaderPlugin } = require('vue-loader') const HtmlWebpackPlugin = require('html-webpack-plugin') const config = merge(baseConfig, { devServer: { port: '8000', host: 'localhost', hot: true, //熱加載 //quiet: true //控制檯中不輸出打包的信息 }, plugins: [ new VueLoaderPlugin(), new HtmlWebpackPlugin(), new webpack.HotModuleReplacementPlugin() ] }) module.exports = config
最後在package裏面添加腳本
"build": "webpack --mode=production --config build/webpack.config.build.js", "dev": "webpack-dev-server --mode=development --progress --config build/webpack.config.dev.js"
執行npm run dev
查看控制檯
這就成功了,在瀏覽器裏面輸入http://localhost:8000/,修改app.vue文件,實現了vue-cli的熱加載了~~~~
接下來完善一下,不能只有.vue文件的loader,其餘的webpack也要認識
咱們配置一下圖片的loader,以及css的loader,同時css使用postcss進行預處理
url-loader 用於將文件轉換爲base64 URI file-loader是依賴loader
npm i url-loader file-loader -D
添加配置webpack.config.base.js>module>rules
{ test: /\.(gif|png|jpg|svg)$/, use: [{ loader: 'url-loader', options: { limit: 2048, name: 'resources/[path][name].[hash:8].[ext]' } }] },
配置css(vue-cli裏面的實現很是友好,有機會能夠去看看) 下面的是最簡單的配置
npm install css-loader -D npm install vue-style-loader -D npm install postcss-loader -D
添加配置webpack.config.base.js>module>rules (postcss不瞭解谷歌一下)
{ test: /\.css$/, use: [ 'vue-style-loader', 'css-loader', { loader: 'postcss-loader', options: { sourceMap: true //啓用源映射支持,postcss-loader將使用其餘加載器給出的先前源映射並相應地更新它 } } ] }
npm install autoprefixer -D
根目錄新建文件postcss.config.js,安裝autoprefixer (自動添加瀏覽器前綴)
const autoprofixer = require('autoprefixer') module.exports = { plugins: [ autoprofixer() ] }
配置到這裏基本的圖片以及css就配置完成了,運行一下試試 npm run dev
我找src下面建立了assets/img/user.jpg
app.vue
<template> <div> 你好 {{ data }} <img src="./assets/img/user.jpg"> </div> </template> <script> export default { data(){ return { data: "Vue Cli" } } } </script> <style> div{ font-size: 20px; color: red; } img { width: 100px; } </style>
實現了開發環境的圖片以及css的配置
打包一下試試
build後生成的目錄是這樣的
這不是咱們想要的,webpack把代碼,類庫,css都打包在一塊兒,這樣不論是上線仍是首屏加載都有影響,因此這裏咱們要優化webpack
在處理以前想安裝一個能夠幫助咱們每次build以前自動刪除上次build生成的文件的插件
clean-webpack-plugin
這個插件不知道爲何,怎麼配置路徑都沒效果
這裏我使用rimraf來進行刪除(vue-cli也是使用rimraf,可是他是寫在代碼裏面)
npm install rimraf -D
在package裏面變一下腳本,讓打包以前幫咱們刪除以前到打包文件
"build-webpack": "webpack --mode=production --config build/webpack.config.build.js", "delete": "rimraf dist", "build": "npm run delete && npm run build-webpack"
它會將全部的入口 chunk(entry chunks)中引用的
*.css
,移動到獨立分離的 CSS 文件
npm install extract-text-webpack-plugin@next -D
由於開發環境和生產環境不同
咱們須要將css部分的代碼分環境配置
module: { rules: [{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "vue-style-loader", use: [ 'css-loader', { loader: 'postcss-loader', options: { sourceMap: true } } ] }) }] },
這樣的話,咱們開發環境不影響依舊是以前到模式,build的時候用ExtractTextPlugin幫咱們分離非js文件,實現css的分離打包
咱們打包一下試試npm run build
接下來是分離js文件,就是將庫文件以及咱們的代碼分離開,利於上線後的瀏覽器緩存,代碼會常常變,庫不會常常變
在webpack4以前js分離用的插件是CommonsChunkPlugin,不過這插件如今移除了,如今用的是optimization.splitChunks 來進行公共代碼與第三方代碼的提取,splitChunks參數以下
optimization: { splitChunks: { chunks: "initial", // 代碼塊類型 必須三選一: "initial"(初始化) | "all"(默認就是all) | "async"(動態加載) minSize: 0, // 最小尺寸,默認0 minChunks: 1, // 最小 chunk ,默認1 maxAsyncRequests: 1, // 最大異步請求數, 默認1 maxInitialRequests: 1, // 最大初始化請求書,默認1 name: () => {}, // 名稱,此選項課接收 function cacheGroups: { // 緩存組會繼承splitChunks的配置,可是test、priorty和reuseExistingChunk只能用於配置緩存組。 priority: "0", // 緩存組優先級 false | object | vendor: { // key 爲entry中定義的 入口名稱 chunks: "initial", // 必須三選一: "initial"(初始化) | "all" | "async"(默認就是異步) test: /react|lodash/, // 正則規則驗證,若是符合就提取 chunk name: "vendor", // 要緩存的 分隔出來的 chunk 名稱 minSize: 0, minChunks: 1, enforce: true, reuseExistingChunk: true // 可設置是否重用已用chunk 再也不建立新的chunk } } } }
官方包括這解釋,我並非很看懂,因此打包策略並非很好
在webpack.config.build.js>config
output: { filename: '[name].[chunkhash:8].js' }, optimization: { splitChunks: { chunks: "all", cacheGroups: { vendor: { test: /node_modules/, //這裏雖然分離了,可是沒有作到按需引入,看官方配置也不是很明白 name: 'vendors', chunks: 'all' } } }, runtimeChunk: true }
build一下查看目錄,能夠看出代碼與庫之間分離了
這裏處理一下git 新建文件.gitignore
.DS_Store node_modules/ /dist/ npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln
處理一下編譯器的統一配置
新建文件 .editorconfig,(關於editorconfig,以及配置解釋)
root = true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf insert_final_newline = true trim_trailing_whitespace = true
還有一點要注意,假如沒有效果,vscode須要安裝一個插件EditorConfig for VS Code
,其餘編譯器不太清楚
處理一下ES6,以及js文件的webpack的loader配置
今天裝了babel-loader8.0.0 報錯報一上午,心態都搞崩了,因此這裏我使用的是7版本
npm install babel-loader@7 babel-core babel-preset-env -D
在webpack.config.base.js>module>rules裏面添加代碼
{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
新建文件 .babelrc
{ "presets": [ "env" ] }
首先檢查開發環境
我新建了一個es6語法的js 導入到app.vue裏面
運行結果
eslint的安裝相對簡單,能夠看官方指南
npm install --save-dev eslint eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
由於.vue文件不會是純js代碼,因此,咱們須要安裝額外的解析的插件
npm install eslint-plugin-html -D
而後咱們配置eslint到咱們的項目
在根目錄新建文件.eslintrc
{ "extends": "standard", "plugins": [ "html" ], "rules": { "no-new": "off" //由於new Vue可是eslint默認不準new 咱們須要把這個關掉 } }
在package裏面添加兩行腳本
"lint": "eslint --ext .js --ext .jsx --ext .vue src/", "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
如今運行npm run lint
即檢查項目
運行npm run lint-fix
,便是將不規範的地方修正
下一步咱們配置到咱們的webpack裏面讓運行的時候同時檢查代碼
npm install eslint-loader babel-eslint -D
改寫配置文件
{ "extends": "standard", "plugins":[ "html" ], "parser":"babel-eslint", "rules": { "no-new": "off" } }
在webpack.config.base裏面的module> rules 裏面加一個字段
{ test: /\.(vue|js|jsx)$/, loader: 'eslint-loader', exclude:/node_modules/, enforce: 'pre' //預處理 }
至此,基本的vue項目骨架的搭建完畢了,後面還有vue-router 以及vuex less的安裝,請查看個人github,固然他沒有vue-cli那麼強大,或許最大的益處是讓咱們熟悉一個vue項目的大體webpack配置,固然咱們能夠一步一步的優化項目