webpack 是一個前端工程化打包工具,對於前端工程師來講 webpack 是一項十分重要的技能。下面咱們就經過搭建一個 vue 項目來學習使用 webpackjavascript
主要環境:css
本項目實現如下功能:html
vue/cli
相似的基本目錄*.vue
,*.css
等文件es6
及以上語法執行npm init
並建立如下目錄前端
demo ├─ dist ├─ public └─ src
npm install -D webpack webpack-cli
npm install -D webpack-dev-server
npm install -D html-webpack-plugin
npm install -D vue-loader vue-template-compiler
npm install -D css-loader style-loader
npm install -D file-loader url-loader
npm install -D @babel/core @babel/cli @babel/preset-env babel-loader
, npm install @babel/polyfill
npm install vue vue-router
新建src/main.js
,並寫入:vue
console.log('Hello Webpack');
根目錄下新建webpack.config.js
,並寫入:java
const path = require('path'); const config = { entry: './src/main.js', // 定義入口文件 output: { path: path.resolve(__dirname + '/dist'), // 打包生成文件地址,必須是絕對路徑 filename: '[name].build.js', // 生成的文件名 }, }; module.exports = config;
在package.json
中的scripts
中添加一個腳本:node
{ ... "scripts": { "build": "webpack --mode=production" } ... }
在命令行中執行npm run build
,此時項目目錄中出現了dist/main.build.js
,證實執行成功webpack
js 文件打包成功後,須要一個 html 文件來引入這個 js 文件,這就須要用到咱們一開始下載的html-webpack-plugin
git
首先新建public/index.html
建立一個基礎頁面:es6
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>webpack搭建vue</title> </head> <body> <!-- 若是瀏覽器禁止加載js腳本 --> <noscript> <strong> We're sorry but this site doesn't work properly without JavaScript enabled. Please enable it to continue. </strong> </noscript> <div id="app"></div> <!-- build後的文件會在這以後自動引入 --> </body> </html>
在public
下隨便放入一個圖標favicon.ico
,而後在webpack.config.js
中配置插件:
const HtmlWebpackPlugin = require('html-webpack-plugin'); const config = { ... plugins:[ new HtmlWebpackPlugin({ filename: 'index.html', // 生成的文件夾名 template: 'public/index.html', // 模板html favicon: 'public/favicon.ico', // 圖標 }), ] } ...
以後再次執行npm run build
,dist
下會生成index.html
,favicon.ico
,main.build.js
三個文件,經過瀏覽器打開index.html
,就能夠發現控制檯輸出了Hello Webpack
,頁面圖標也變成了本身設定的圖標,經過編輯器打開index.html
,咱們會發現 webpack 幫助咱們自動引入了favicon.ico
和main.build.js
:
<!DOCTYPE html> <html> <head> ... <link rel="icon" href="favicon.ico" /> </head> <body> ... <script src="main.build.js"></script> </body> </html>
webpack 熱加載須要用到webpack-dev-server
,在開始咱們已經安裝過了,在webpack.config.js
中配置:
const config = { ... devServer: { contentBase: path.join(__dirname, 'dist'), // html所在路徑 compress: true, // 是否壓縮 port: 3000, // 端口 hot: true, // 熱部署 open: true, // 打包完成後自動打開網頁 } }
增長package.json
腳本:
{ ... "scripts": { "build": "webpack --mode=production", "serve": "webpack serve" } ... }
執行npm run serve
,打包成功後會自動打開網頁,而且當你修改src/main.js
或src/index.html
的內容的時候,瀏覽器會自動從新打包並刷新
讓 webpack 打包*.vue
文件須要vue-loader
和vue-template-compiler
,同時爲了 webpack 可以解析 vue 中的 css 還須要用到css-loader
和vue-style-loader
,在webpack.config.js
配置以上插件:
... const { VueLoaderPlugin } = require('vue-loader'); const config = { ... // loaders module: { rules: [ { // *.vue test: /\.vue$/, loader: 'vue-loader', }, { // `*.vue` 文件中的 `<style>` 塊以及普通的`*.css` test: /\.css$/, use: ['vue-style-loader', 'css-loader'], }, ], }, plugins: [ ... new VueLoaderPlugin(), ], ... }; ...
配置完後新建src/App.vue
:
<template> <div class="example"> {{ msg }} </div> </template> <script> export default { data() { return { msg: 'Hello Webpack', }; }, }; </script> <style> .example { color: red; } </style>
修改src/main.js
:
import Vue from 'vue'; import App from './App.vue'; new Vue({ el: '#app', render: (h) => h(App), });
而後運行npm run serve
,便可看到頁面上顯示的Hello Webpack
使用file-loader
或url-loader
加載,它們都是用於打包文件和圖片資源的,區別在於url-loader
封裝了file-loader
在訪問網站時若是圖片較多,會發不少 http 請求,會下降頁面性能。這個問題能夠經過 url-loader
解決。url-loader
會將引入的圖片編碼,生成 dataURl。至關於把圖片數據翻譯成一串字符,再把這串字符打包到文件中,最終只須要引入這個文件就能訪問圖片了。
固然,若是圖片較大,編碼會消耗性能。所以 url-loader
提供了一個 limit 參數,小於 limit 字節的文件會被轉爲 DataURl,大於 limit 的還會使用 file-loader 進行 copy。
此處咱們使用 url-loader
,因爲它是基於 file-loader
的封裝,因此也須要引入 file-loader
。
... const config = { ... module: { rules: [ ... { // 圖片 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: { loader: 'url-loader', options: { limit: 25000, }, }, }, ], }, }; ...
而後添加一個圖片src/assets/logo.png
,在App.vue
中引入:
<template> <div class="example"> {{ msg }} <img :src="url" /> </div> </template> <script> import logo from './assets/logo.png'; export default { data() { return { msg: 'Hello Vue1', url: logo, }; }, }; </script> <style> .example { color: red; } </style>
再次npm run serve
便可看到圖片
babel 能夠將 js 的高版本(es6)語法轉換爲低版本,使得項目兼容低版本瀏覽器
須要咱們注意的是,babel7 與 babel6 不兼容,所以須要使用最新版本的 babel 和 babel 插件,在前面文章開始咱們已經安裝了 babel7 版本的 babel 插件,下面咱們在webpack.config.js
中配置它:
... const config = { ... module: { rules: [ ... { // *.js test: /\.js$/, exclude: /node_modules/, // 不編譯node_modules下的文件 loader: 'babel-loader', }, ], }, }; ...
配置完後在項目根目錄下建立一個 babel 的配置文件.babelrc
,寫入以下內容:
{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "entry" } ] ] }
更多 babel 配置請查看babel 中文官網
配置完成後新建一個src/utils/getData.js
測試一下:
export default function getData() { return new Promise((resolve, reject) => { resolve('ok'); }); }
在src/App.vue
中引入:
<template> <div class="example"> {{ msg }} <img :src="url" /> </div> </template> <script> import logo from './assets/logo.png'; import getData from './utils/getData'; export default { data() { return { msg: 'Hello Vue1', url: logo, }; }, methods: { async fetchData() { const data = await getData(); this.msg = data; }, }, created() { this.fetchData(); }, }; </script> <style> .example { color: red; } </style>
從新執行npm run serve
後,頁面顯示ok
,babel 引入成功
爲了方便開發,咱們能夠給 src 目錄設置別名,以及將經常使用文件類型的後綴省略
... const config = { ... // 解析路徑 resolve: { // 設置src別名 alias: { '@': path.resolve(__dirname, 'src'), }, //後綴名 能夠根據須要自由增減 extensions: ['.js', '.vue'], }, ... }; ...
這樣咱們就能夠以以下方式導入 vue 和 js 文件:
// 導入App.vue import App from '@/App'; // 導入getData import getData from '@/utils/getData';
至此,咱們已經簡單的搭建出了 vue 項目,在項目中咱們可能還會須要用到less
,sass
,字體圖標等工具,針對這類工具 webpack 都有與其對應的loader
或plugin
,須要時搜索他們的文檔便可。