都 8102 年了,现在还来谈 webpack 的配置,额,是有点晚了.而且,基于 vue-cli 或者 create-react-app 生成的项目,也已经一键为我们配置好了 webpack,看起来似乎并不需要我们深入了解.
不过,为了学习和理解 webpack 解决了前端的哪些痛点,还是有必要从零开始自己搭建一个简单的开发环境.本文的 webpack 配置参考了 vue-cli 提供 webpack-simple 模板,这也是 vue-cli 里面最简单的一个 webpack 配置,非常适合从零开始学习.
注: 本文 webpack 基于 3.10.0
演示代码下载
安装 webpack
npm i webpack -g
项目初始化
新建一个文件夹 vue-webpack-simple
新建 package.json
npm init -y
安装 vue webpack webpack-dev-server
根目录下新建 index.html
npm i vue --save
npm i webpack webpack - dev - server--save - dev
根目录下新建 webpack.config.js
<!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>Document</title>
</head>
<body>
</body>
</html>
新建 src 文件夹,src 文件夹下新建 main.js
var path = require('path');
var webpack = require('webpack');
module.exports = {};
目前整个项目的结构如下:
js 模块化
在 ES6 出现之前,js 是没有统一的模块体系. 服务器端使用 CommonJS 规范, 而浏览器端又有 AMD 和 CMD 两种规范
webpack 的思想就是一切皆模块,官方推荐使用 commonJS 规范,这使得我们浏览器端也可以使用 commonJS 的模块化写法
module.exports = {}
src 目录下新建一个 util.js
修改 webpack.config.js
module.exports = function say() {
console.log('hello world');
}
main.js
var say = require('./util');
say();
修改 package.josn
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js', // 项目的入口文件,webpack会从main.js开始,把所有依赖的js都加载打包
output: {
path: path.resolve(__dirname, './dist'), // 项目的打包文件路径
publicPath: '/dist/', // 通过devServer访问路径
filename: 'build.js' // 打包后的文件名
},
devServer: {
historyApiFallback: true,
overlay: true
}
};
注意:webpack-dev-server 会自动启动一个静态资源 web 服务器 --hot 参数表示启动热更新
"scripts": {
"dev": "webpack-dev-server --open --hot",
"build": "webpack --progress --hide-modules"
},
修改 index.html,引入打包后的文件
运行
<!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>Document</title>
</head>
<body>
<script src="/dist/build.js"></script>
</body>
</html>
npm run dev
可以发现浏览器自动打开的一个页面,查看控制台,有 hello world 打出
我们随意修改 util.js,可以发现浏览器会自动刷新,非常方便.
如果我们希望看打包后的 bundle.js 文件,运行
npm run build
可以看到生成了一个 dist 目录,里面就有打包好后的 bundle.js
webpack 默认不支持转码 es6,但是 import export 这两个语法却单独支持.所以我们可以改写前面的模块化写法
引入 vue
util.js export
default
function say() {
console.log('hello world ');
}
main.js import say from './util';
say();
下面我们来试着引入 vue(目前不考虑单文件. vue)
还要注意一点:要修改 webpack.config.js 文件
main.js
import Vue from 'vue';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
index.html
<!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>Document</title>
</head>
<body>
<div id="app">
{{message}}
</div>
<script src="/dist/build.js"></script>
</body>
</html>
'vue
var path = require('path');
var webpack = require('webpack');
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'build.js'
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
重新运行npm run dev,可以看到,页面正常显示了Hello World
引入sCSS和css
webpack默认只支持js的模块化,如果需要把其他文件也当成模块引入,就需要相对应的loader解析器
npm i node-sass css-loader vue-style-loader sass-loader --save-dev
webpack.config.js
var path = require('path ');
var webpack = require('webpack ');
module.exports = {
entry: '. / src / main.js ',
output: {
path: path.resolve(__dirname, '. / dist '),
publicPath: ' / dist / ',
filename: 'build.js '
},
devServer: {
historyApiFallback: true,
overlay: true
},
resolve: {
alias: {
'vue解释: {
}这段代码意思是:匹配后缀名为css的文件,
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
然后分别用css - loader,vue - style - loader去解析解析器的执行顺序是从下往上 (先css - loader再vue - style - loader)注意:因为我们这里用vue开发,所以使用vue - style - loader,其他情况使用style - loader css - loader使得我们可以用模块化的写法引入css,
vue - style - loader会将引入的css插入到html页面里的style标签里要引入scss也是同理的配置写法: module: {
}我们现在来试下在src目录下新建style目录,style目录里新建common.scss body {
rules: [{
test: /\.css$/,
use: ['vue-style-loader', 'css-loader'],
},
{
test: /\.scss$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.sass$/,
use: ['vue-style-loader', 'css-loader', 'sass-loader?indentedSyntax'],
}]
main.js import './style/common.scss';发现css样式有用了使用babel转码ES6的语法大多数浏览器依旧不支持,
background: #fed;
}
bable可以把ES6转码成ES5语法,这样我们就可以大胆的在项目中使用最新特性了npm i babel - core babel - loader babel - preset - env babel - preset - stage - 3--save - dev在项目根目录新建一个.babelrc文件 {
webpack.config.js添加一个loader {
"presets": [["env", {
"modules": false
}], "stage-3"]
}
exclude表示忽略node_modules文件夹下的文件,不用转码现在我们来试下async await语法吧util.js export
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
}
});这时控制台会报一个错误regeneratorRuntime is not defined,因为我们没有安装babel - polyfill npm i babel - polyfill--save - dev然后修改webpack.config.js的入口entry: ['babel-polyfill', './src/main.js'],
default
function getData() {
return new Promise((resolve, reject) = >{
resolve('ok');
})
}
main.js import getData from './util';
import Vue from 'vue';
import './style/common.scss';
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
methods: {
async fetchData() {
const data = await getData();
this.message = data;
}
},
created() {
this.fetchData();
}
重新npm run dev,可以发现正常运行了引入图片资源把图片也当成模块引入npm i file - loader--save - dev webpack.config.js添加一个loader {
}在src目录下新建一个img目录,存放一张图片logo.png修改main.js import getData from './util';
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
import Vue from 'vue';
import './style/common.scss';
Vue.component('my-component', {
template: '<img :src="http://www.h3399.cn/uploads/body/user-gold-cdn.xitu.io/2018/1/10/160dfc7080ac595f_1c3ccd9fb999e7686c64465cf0d93657948018991.png">
可以看见,压缩效果非常明显!
至此,一个非常简单的 vue 开发环境搭建成功.
注意:本文中的配置还有非常多可以优化的地方,比如分离 js 和 css
读者可以自行了解相关知识,这里只是带领大家了解最基础的 webpack 配置.
来源: https://juejin.im/post/5a55f583518825734f5299aa