通用性的提升,往往伴随着个性化的减弱。Vue Cli 的开箱即用,简单到几乎看不到配置,但对于想要去“把玩” webpack
的开发者来说无疑很不友好。虽然你可以通过 vue.config.js
来调整 webpack
配置,但这种“玩法”中存在黑箱。
这里说的“玩法”是指的是比如对 webpack loader
的探究、babel plugin
的探究、eslint plugin
的探究、一个项目中同时运行 Vue
和 React
的探究,乃至对于跨端框架用 AST
编译的探究等等。由于 github 上存在很多“烂大街”的脚手架,比如这种:
基本骨架:Webpack@4.43.0、babel-loader@7.1.5、postcss-loader@3.0.0
业务技术栈:、Vue@2.6.11(可以切换为React)
先新建一个文件 pure-vue
:
mkdir pure-vue && cd pure-vue 复制代码
然后初始化 package.json
,(一路回车即可):
npm init 复制代码
然后我们在项目中创建几个文件夹:
mkdir src build dist 复制代码
src 存放业务代码,build 存放打包配置、dist 存放打包后的文件。 然后在 src 下创建入口
touch ./src/index.js 复制代码
根目录下创建入口 index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"></div> </body> </html> 复制代码
后面 js 会在打包时将静态资源 bundles
文件插入html中,打包后打入 dist 文件中。
在 build
文件夹下创建以下文件,终端输入:
cd build/ && touch build.js webpack.base.conf.js webpack.dev.conf.js webpack.prod.conf.js 复制代码
我们将获得以下文件:
. ├── build.js ├── webpack.base.conf.js ├── webpack.dev.conf.js └── webpack.prod.conf.js 复制代码
安装 webpack 4.x
相关第三方包:
npm install webpack-merge clean-webpack-plugin webpack-dev-server html-webpack-plugin -D 复制代码
其中:
output.path directory
目录中的文件webpack.base.conf.js
是用于项目中开发环境和生成环境 共用 的 webpack
配置,里面包含了最基本的配置内容:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { bundle: path.resolve(__dirname, '../src/index.js') }, output: { path: path.resolve(__dirname, '../dist'), filename: '[name].[hash].js' }, module: { rules: [ ] }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../index.html') }) ] }; 复制代码
以上配置仅仅包含了打包入口、打包出口、html 模板。
const merge = require("webpack-merge"); const path = require("path"); const baseConfig = require("./webpack.base.conf"); module.exports = merge(baseConfig, { mode: "development", devtool: "inline-source-map", module: { rules: [ // 自己拓展着玩呀 ], }, devServer: { contentBase: path.resolve(__dirname, "../dist"), open: true, }, }); 复制代码
以上配置包含开发环境的 mode
、是否生成 source-map
等。
const merge = require("webpack-merge"); const path = require("path"); const baseConfig = require("./webpack.base.conf"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = merge(baseConfig, { mode: "production", devtool: "source-map", module: { rules: [ // 自己拓展着玩呀 ], }, plugins: [ new CleanWebpackPlugin({ root: path.resolve(__dirname, "../"), verbose: true, dry: false, }), ], }); 复制代码
以上配置包含开发环境的 mode
、是否生成 source-map
等、打包前需要清理的打包文件夹等。
const webpack = require('webpack'); const config = require('./webpack.prod.conf'); webpack(config, (err, stats) => { if (err || stats.hasErrors()) { console.error(err); // 错误打印 return; } }); 复制代码
以上配置仅用于生成环境下的错误打印。
"scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "build": "node build/build.js" }, 复制代码
为了配置以上测试的有效性,我们可以在业务目录 src/idnex.js
中写如代码:
const a = 1; console.log(a); 复制代码
然后执行:
npm run dev 复制代码
这就表示你的脚手架基本工作已经完成,在此基础上,你可以选择用 Vue
或 React
,对应只需要安装不同的 loader
就行。(本文我们以 vue 为示例)
安装 vue 相关 npm 包:
npm i vue -S 复制代码
业务工程目录是 src
,我们在业务工程中写入 vue
入口配置:
./src/index.js
// 项目启动 import Vue from "vue"; import App from "./App"; new Vue({ render: (h) => h(App), }).$mount("#app"); // 渲染挂载 复制代码
然后在 ./src/App.vue 写入一个最简单的 Hello world:
<template> <div> Hello {{msg}}! </div> </template> <script> export default{ data: () => ({ msg: 'Vue', }) } </script> 复制代码
此时终端会出现:
细心的同学可能会观察到,这是由于我们之前配置的 webpack
配置中没有加入任何 loader
,所以我们需要对这个 vue
的工程配置 vue
专用的 loader
。不然无法正常解析它的语法。
npm install vue-loader vue-template-compiler -D 复制代码
还需要将代码中可能出现的ES6语法转为ES5,所以还需要安装 babel:
npm install babel-loader babel-core babel-preset-env -D 复制代码
根目录新建文件 .babelrc,配置:
{ "presets": [ ["env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }] ] } 复制代码
上述代码用于告诉babel我需要你帮我转为需要兼容哪些环境所对应的代码。
webpack.base.conf.js
中配置:
resolve: { extensions: ['*', '.js', '.json', '.vue'], }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader' }, { test: /\.js$/, use: 'babel-loader', exclude: /node_modules/ }, ] }, 复制代码
在 webpack.base.conf.js
中配置
const VueLoaderPlugin = require('vue-loader/lib/plugin'); plugins: [ new HtmlWebpackPlugin({ template: path.resolve(__dirname, '../index.html') }), + new VueLoaderPlugin(), ] 复制代码
此时,浏览器将显示:
这就表明搭建成功了。此时我们需要将文字添加样式,同样的,我们需要去设置对应的 loader
:
npm install postcss-loader autoprefixer -D 复制代码
在 webpack.base.conf.js
中配置:
{ test: /\.css$/, use: ['vue-style-loader', 'css-loader'] } 复制代码
在根目录新建 postcss.config.js
,自动添加前缀:
module.exports = { plugins: [ require('autoprefixer') ] } 复制代码
至此,我们完成了这个最为“纯净”vue的脚手架,其他东西我们可以根据自己需要去“添砖加瓦”!
1、没有多余的第三方 npm 包,每个包的作用你都一清二楚(package.json),缺一不可:
"dependencies": { "vue": "^2.6.11" // vue }, "devDependencies": { "autoprefixer": "^6.7.7", // css 自动添加前缀 "babel-core": "^6.26.3", // babel 核心库 "babel-loader": "^7.1.5", // webapck 对js编译loader "babel-preset-env": "^1.7.0", // js 编译需要的环境 "clean-webpack-plugin": "^3.0.0", // 打包前清除dist目录 "css-loader": "^3.5.3", // css 的loader "html-webpack-plugin": "^4.0.0-beta.14", // 生成 html "postcss-loader": "^3.0.0", // css loader "vue-loader": "^15.9.2", // vue 对应loader "vue-style-loader": "^4.1.2", // vue 样式对应loader "vue-template-compiler": "^2.6.11", // vue template 对应loader "webpack": "^4.43.0", // webpack "webpack-cli": "^3.3.11", // webapck cli "webpack-dev-server": "^3.11.0" // webpack 服务 }, 复制代码
2、webpack 配置透明: 除了公共配置,开发环境和生成环境等你自己去配置“玩”,此处可以自己手写一些 loader 玩玩: