項目git地址css
__dirname: 獲取當前文件所在路徑,等同於path.dirname(__filename)html
console.log(__dirname); // Prints: /Users/mjr console.log(path.dirname(__filename)); // Prints: /Users/mjr
path.resolve([..paths]): 把一個路徑或路徑片斷的序列解析爲一個絕對路徑vue
- 給定的路徑的序列是從右往左被處理的,後面每一個 path 被依次解析,直到構造完成一個絕對路徑
- 若是處理徹底部給定的 path 片斷後還未生成一個絕對路徑,則當前工做目錄會被用上
- 生成的路徑是規範化後的,且末尾的斜槓會被刪除,除非路徑被解析爲根目錄
- 長度爲零的 path 片斷會被忽略
- 若是沒有傳入 path 片斷,則 path.resolve() 會返回當前工做目錄的絕對路徑
path.resolve('/foo/bar', './baz'); // 返回: '/foo/bar/baz' path.resolve('/foo/bar', '/tmp/file/'); // 返回: '/tmp/file' path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif'); // 若是當前工做目錄爲 /home/myself/node, // 則返回 '/home/myself/node/wwwroot/static_files/gif/image.gif'
項目目錄生成以下文件node
. ├── build │ ├── build.js │ ├── index.html │ ├── webpack.base.conf.js │ ├── webpack.dev.conf.js │ └── webpack.prod.conf.js ├── package.json ├── package-lock.json └── src ├── App.vue ├── main.js ├── timg.gif └── timg.jfif
首先,先裝下webpack依賴:jquery
npm i webpack webpack webpack-cli -D
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { bundle: path.resolve(__dirname, '../src/main.js') }, output: { path: path.resolve(__dirname, '../dist'), filename: '[name].[hash].js', publicPath: '/' }, module: { rules: [ ] }, plugins: [ <!-- 以當前目錄的index.html爲模板生成新的index.html,這個插件就是將新生成的文件(js,css)引入 --> new HtmlWebpackPlugin({ template: path.resolve(__dirname, 'index.html') }) ], resolve: { } };
上面用到了html-webpack-plugin插件,裝下:webpack
npm i html-webpack-plugin -D
const merge = require('webpack-merge'); const path = require('path'); const baseConfig = require('./webpack.base.conf'); module.exports = merge(baseConfig, { // mode關係到代碼壓縮質量 https://webpack.docschina.org/guides/tree-shaking/ mode: 'development', // source-map,將編譯後的代碼映射到原代碼,便於報錯後定位錯誤 devtool: 'inline-source-map', <!-- webpack-dev-server配置項 --> devServer: { <!-- devserver啓動服務的根路徑 --> contentBase: path.resolve(__dirname, '../dist'), <!-- 打開瀏覽器 --> open: true } });
合併webpack配置的插件webpack-merge,可以啓一個簡易服務的webpack-dev-server,詳情git
npm i webpack-dev-server webpack-merge -D
const merge = require('webpack-merge'); const CleanWebpackPlugin = require('clean-webpack-plugin'); const path = require('path'); const baseConfig = require('./webpack.base.conf'); module.exports = merge(baseConfig, { mode: 'production', devtool: 'source-map', module: { rules: [] }, plugins: [ new CleanWebpackPlugin(['dist/'], { root: path.resolve(__dirname, '../') }) ] });
清除文件的插件:github
npm i clean-webpack-plugin -D
const webpack = require('webpack'); const config = require('./webpack.prod.conf'); webpack(config, (err, stats) => { if (err || stats.hasErrors()) { // 在這裏處理錯誤 console.error(err); return; } // 處理完成 console.log(stats.toString({ chunks: false, // 使構建過程更靜默無輸出 colors: true // 在控制檯展現顏色 })); });
// package.json { +++ "scripts": { "build": "node build/build.js", "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js" }, }
以上算是一個webpack的基本結構,若是入口文件(main.js)裏引入的是正經js,npm dev和npm build是能夠的打包編譯的,可是咱們是要寫vue,那就要加些loader和plugins了web
依賴安裝要求:webpack 4.x | babel-loader 7.x | babel 6.x,注意babel-loader和babel的版本,否則會報錯vue-router
npm install -D babel-loader@7 babel-core babel-preset-env webpack
而後再配置中加入
// base.conf.js module.exports = { +++ module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', } }, +++ ] } }
咱們還須要添加一個配置文件(.babelrc)在根目錄下:
/// .babelrc { "presets": [ ["env", { "targets": { "browsers": [">0.25%", "last 2 versions", "not ie 11", "not op_mini all"] } }] ] }
這就是 babel-preset-env 的做用,幫助咱們配置 babel。咱們只須要告訴它咱們要兼容的狀況(目標運行環境),它就會自動把代碼轉換爲兼容對應環境的代碼。
以上代碼表示咱們要求代碼兼容最新兩個版本的瀏覽器,不用兼容 11(及如下)和Opera Mini,另外市場份額超過 0.25% 的瀏覽器也必須支持。
只須要告訴 babel-preset-env 你想要兼容的環境,它就會自動轉換
若是咱們但願在頁面引入圖片(包括img的src和background的url)。當咱們基於webpack進行開發時,引入圖片會遇到一些問題
其中一個就是引用路徑的問題。拿background樣式用url引入背景圖來講,咱們都知道,webpack最終會將各個模塊打包成一個文件,所以咱們樣式中的url路徑是相對入口html頁面的,而不是相對於原始css文件所在的路徑的。這就會致使圖片引入失敗。這個問題是用file-loader解決的,file-loader能夠解析項目中的url引入(不只限於css),根據咱們的配置,將圖片拷貝到相應的路徑,再根據咱們的配置,修改打包後文件引用路徑,使之指向正確的文件
另外,若是圖片較多,會發不少http請求,會下降頁面性能。這個問題能夠經過url-loader解決。url-loader會將引入的圖片編碼,生成dataURl。至關於把圖片數據翻譯成一串字符。再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。固然,若是圖片較大,編碼會消耗性能。所以url-loader提供了一個limit參數,小於limit字節的文件會被轉爲DataURl,大於limit的還會使用file-loader進行copy。
url-loader和file-loader是什麼關係呢?簡答地說,url-loader封裝了file-loader。url-loader賴於file-loader,即便用url-loader時,也要安裝file-loader
npm i url-loader file-loader -D
/// base.conf.js module.exports = { +++ module: { rules: [ +++ { test: /\.(png|jpg|jfif|jpeg|gif)$/, use: [ { loader: 'url-loader', options: { // 低於這個limit就直接轉成base64插入到style裏,否則以name的方式命名存放 // 這裏的單位時bit limit: 8192, name: 'static/images/[hash:8].[name].[ext]' } } ] }, // 字體圖標啥的,跟圖片分處理方式同樣 { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ { loader: 'url-loader', name: 'static/font/[hash:8].[name].[ext]' } ] }, ] }, }
做用本身去看
npm i vue-loader -D
// base.conf.js module.exports = { +++ module: { rules: [ +++ { test: /\.vue$/, loader: 'vue-loader' } ] } }
在這裏還要一個插件,這個插件是必須的!
// base.conf.js const VueLoaderPlugin = require('vue-loader/lib/plugin') module.exports = { +++ plugins: [ // 它的職責是將你定義過的其它規則複製並應用到 .vue 文件裏相應語言的塊。 // 例如,若是你有一條匹配 /\.js$/ 的規則,那麼它會應用到 .vue 文件裏的 <script> 塊 new VueLoaderPlugin(), +++ ] }
npm i less-loader css-loader style-loader less autoprefixer postcss-loader -D
const StyleLintPlugin = require('stylelint-webpack-plugin'); // base.conf.js module.exports = { +++ module: { rules: [ { // less css test: /\.l?css$/, // use裏的loader執行順序爲從下到上,loader的順序要注意 // 這裏檢測到less/css文件後須要將後續處理loader都寫在此use裏,若是less和css過度開檢測處理,不能說先用less-loader轉成css,而後讓它走/\.css/裏的use use: [ {loader: 'style-loader'}, {loader: 'css-loader'}, {loader: 'postcss-loader'}, {loader: 'less-loader'}, ] }, +++ ] } }
在根目錄新建個postcss.config.js文件來配置autoprefixer,經過 Browerslist來幫助你配置,瀏覽器市場份額,瞭解下 browserl.ist
module.exports = { plugins: [ require('autoprefixer')({ "browsers": [ "defaults", "not ie < 9", "last 2 versions", "> 1%", "iOS 7", "last 3 iOS versions" ] }) ] }
這裏打包css
以less
爲例,r若是要用mini-css-extract-plugin
插件提取css
,將上面改成以下:
npm install mini-css-extract-plugin -D
const MiniCssExtractPlugin = require('mini-css-extract-plugin') +++ module.exports = { +++ // 模塊,loader module: { rules: [ +++ { test: /\.l?(c|e)ss$/, use: [ MiniCssExtractPlugin.loader, {loader: 'css-loader'}, {loader: 'postcss-loader'}, {loader: 'less-loader'}, ] }, +++ ] }, // 插件 plugins: [ +++ new MiniCssExtractPlugin({ filename: 'static/css/[name].[hash].css', chunkFilename: 'static/css/[name].[hash].css' }) ] }
// base.conf.js module.exports = { +++ resolve: { alias: { // 配置別名'vue$',否則import 'vue'時,webpack找不到 'vue$': 'vue/dist/vue.esm.js', // 這個爲src配置別名,非必需,爲方便而已 '@': path.resolve(__dirname, '../src') }, // 在import這些拓展名的文件時,能夠省略拓展名 extensions: ['*', '.js', '.json', '.vue'], } }
如今咱們來測試如下,安裝一個vue
npm i vue
在mian.js裏面
import Vue from 'vue' import App from './App' new Vue({ el: '#app', components: {App}, template: '<App/>' })
在App.vue裏寫入
<template> <div> <h3 class="title">{{title}}</h3> <p class="content">{{content}}</p> <div class="goddess"> <div class="right"> <h4 class="right__h4">background引入圖片</h4> <div class="right__img"></div> </div> <div class="left"> <h4 class="left__h4">img標籤直接引入圖片</h4> <img class="left__img" src="./timg.jfif" /> </div> </div> </div> </template> <script> export default { components: { Foot: Footer }, data () { return { title: 'hello word', content: 'webpack4 搭建vue環境', } }, } </script> <style lang="less" scoped> .title { font-size: 20px; text-align: center; color: red; } .content { font-size: 14px; color: #333333; } .goddess { .left { margin-left: 50%; &__h4 { font-size: 14px; } &__img { width: 308px; height: 433px; } } .right { float: left; &__h4 { font-size: 14px; } &__img { width: 300px; height: 150px; background: url('./timg.gif') no-repeat; } } } </style>
好了,npm dev 先看一下女神,放鬆一下:
使用 splitChucksPlugin 插件,這是 Webpack 自帶的,不用安裝第三方依賴,默認配置便可
<!-- base.conf.js --> module.exports = { +++ plugins: [ +++ new webpack.optimize.SplitChunksPlugin() ] }
每次咱們對項目進行打包時,咱們都會把引用的第三方依賴給打包一遍,好比 Vue、Vue-Router、React 等等。可是這些庫的代碼基本都是不會變更的,咱們不必每次打包都構建一次,因此咱們最好將這些第三方庫提取出來單獨打包,這樣有利於減小打包時間。
官方插件是 DllPlugin。推薦一個比較好用的插件 —— autodll-webpack-plugin
npm i autodll-webpack-plugin -D
// base.conf.js module.exports = { +++ plugins: [ // 將一些不太可能改動的第三方庫單獨打包,會經過緩存極大提高打包速度 new AutoDllPlugin({ // will inject the DLL bundle to index.html // default false inject: true, debug: false, filename: '[name]_[hash].js', path: 'static', entry: { // [name] = vue, 在這裏會將entry裏的每一個item(vue,jquery)都打包成一個js vue: [ 'vue', 'vue-router' ], // [name] = jquery // jquery: [ // 'jquery', // 'jquery-from' // ] } }), +++ ] }
inject 爲 true,插件會自動把打包出來的第三方庫文件插入到 HTML。filename 是打包後文件的名稱。path 是打包後的路徑。entry 是入口,vendor 是你指定的名稱,數組內容就是要打包的第三方庫的名稱,不要寫全路徑,Webpack 會自動去 node_modules 中找到的。
每次打包,這個插件都會檢查註冊在 entry 中的第三方庫是否發生了變化,若是沒有變化,插件就會使用緩存中的打包文件,減小了打包的時間,這時 Hash 也不會變化。
「熱重載」不僅是當你修改文件的時候簡單從新加載頁面。啓用熱重載後,當你修改 .vue 文件時,該組件的全部實例將在不刷新頁面的狀況下被替換。它甚至保持了應用程序和被替換組件的當前狀態!當你調整模版或者修改樣式時,這極大地提升了開發體驗,如下兩種方式擇一便可
--hot
選項就ok了,webpack,vue-loader "scripts": { +++ "dev": "webpack-dev-server --hot --inline --progress --config build/webpack.dev.conf.js" },
const webpack = require('webpack') module.exports = { +++ module: { devServer: { +++ // 開啓熱重載 hot: true }, plugins: [ // 啓用模塊熱替換(HMR) new webpack.HotModuleReplacementPlugin(), // 當開啓 HMR 的時候使用該插件會顯示模塊的相對路徑,建議用於開發環境。 new webpack.NamedModulesPlugin(), +++ ] } }
確保 VS Code
安裝了 Vetur(設置編輯器支持vue文件,若是寫過vue忽略)
和 Eslint
插件
npm i -g eslint@latest eslint --init
而後選個最流行的就好了
會幫你新建一個.eslintrc.js 的配置文件以及裝一些 eslint 的依賴
在 package.json 里加上:
{ +++ "scripts": { +++ "lint": "eslint --ext .js,.vue src" }, }
你能夠嘗試的npm run lint
,你會發現spacing 系列
、no-new
、.vue語法不支持
等問題
固然,你能夠經過改寫 lint 命令(加個--fix
)來解決部分語法報錯
{ +++ "scripts": { +++ "lint": "eslint --fix --ext .js,.vue src" }, }
或者保存的時候讓 eslint 插件自動修復。 更改 VS Code 中的 eslint.autoFixOnSave 設置,勾選文本編輯->Format On Save
固然這玩法不是咱們這裏的重點,安裝 eslint-plugin-html 來解決vue語法eslint報錯問題
npm install -D eslint-plugin-html
在.eslintrc.js 中配置 eslint-plugin-html
module.exports = { +++ "plugins": [ // 使用eslint-plugin-html "html" ] };
至於 main.js 裏的 new 指定給變量錯誤 disable 掉
+++ /* eslint-disable no-new */ new Vue({ el: '#app', components: { App }, template: '<App/>' })
npm i eslint-loader babel-eslint -D
<!-- .eslintrc.js --> { +++ "parser": "babel-eslint" }
<!-- base.config.js --> module.exports = { module: { rules: [ { test: /\.(vue|js)$/, loader: 'eslint-loader', exclude: /node_modules/, // 預處理 enforce: 'pre', include: [path.join(__dirname, '..', 'src')] } ] } }
npm i husky -D
<!-- package.json --> { +++ "script": { +++ "precommit": "eslint --fix --ext .js --ext .vue src/" } }
該工具能夠在咱們提交代碼時,調用"precommit"鉤子,執行預處理操做,eslint不經過,沒法提交
在提交時僅對git add
的 js,vue 文件進行檢測lint-staged 和 husky 在 pre-commit 階段作代碼檢查
npm i lint-staged -D
<!-- package.json --> { +++ "script": { +++ "precommit": "lint-staged" }, "lint-staged": { "src/**/*.{js,vue}": [ "eslint --fix", "git add" ] }, }
npm i juery -D
<!-- base.config.js --> module.exports = { +++ plugins: [ +++ new webpack.ProvidePlugin({ $: 'jquery' }) ] };
這樣就能夠將$當全局變量使用了,固然eslint要配置個global,這裏不介紹了
對你有幫助的話點個刷波6,點個贊吧
原文地址:https://segmentfault.com/a/1190000016972438