├── .babelrc
├── .editorconfig
├── .eslintrc
├── LICENSE
├── package-lock.json
├── package.json
├── postcss.config.js
├── readme.md
├── src
├── App.vue
├── images
│ └── logo_my.png
├── index.html
├── index.js
├── router
│ └── router.js
└── style
│ └── index.scss
├── webpack.analy.js
├── webpack.build.js
├── webpack.config.js
└── webpack.server.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"]
3 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "plugins": [
4 | "react",
5 | "vue"
6 | ],
7 | "parserOptions": {
8 | "ecmaVersion": 6,
9 | "sourceType": "module",
10 | "ecmaFeatures": {
11 | "jsx": true
12 | }
13 | },
14 | "env": {
15 | "browser": true,
16 | "amd": true,
17 | "es6": true,
18 | "node": true,
19 | "mocha": true
20 | },
21 | "rules": {
22 | "global-strict": 0,
23 | "no-underscore-dangle": 0,
24 | "no-console": 0,
25 | "no-trailing-spaces": [1, { "skipBlankLines": true }], //不允许在语句后存在多余的空格
26 | "no-alert": 0,
27 | "react/jsx-uses-react": 1,
28 | "react/jsx-uses-vars": 1,
29 |
30 | // allow async-await
31 | "generator-star-spacing": "off",
32 | // allow debugger during development
33 | // "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
34 |
35 | "space-before-function-paren": 0, // 强制在 function的左括号之前使用一致的空格
36 |
37 |
38 |
39 | //警告
40 | "quotes": ["warn", "single"], //建议使用单引号
41 | // "no-inner-declarations": [1, "both"], //不建议在{}代码块内部声明变量或函数
42 | "no-extra-boolean-cast": 1, //多余的感叹号转布尔型
43 | "no-extra-semi": 1, //多余的分号
44 | "semi": ["off", "always"], // js语句结尾必须使用分号
45 | "no-extra-parens": 1, //多余的括号
46 | "no-empty": 1, //空代码块
47 | "no-use-before-define": [1, "nofunc"], //使用前未定义
48 | "complexity": [1, 25], //圈复杂度大于25 警告
49 |
50 |
51 |
52 | //常见错误
53 | "comma-dangle": [0, "never"], //定义数组或对象最后多余的逗号
54 | // "no-debugger": 2, //debugger 调试代码未删除
55 | "no-constant-condition": 2, //常量作为条件
56 | "no-dupe-args": 2, //参数重复
57 | "no-dupe-keys": 2, //对象属性重复
58 | "no-duplicate-case": 2, //case重复
59 | "no-empty-character-class": 2, //正则无法匹配任何值
60 | "no-invalid-regexp": 2, //无效的正则
61 | "no-func-assign": 2, //函数被赋值
62 | "valid-typeof": 2, //无效的类型判断
63 | "no-unreachable": 2, //不可能执行到的代码
64 | "no-unexpected-multiline": 1, //行尾缺少分号可能导致一些意外情况
65 | "no-sparse-arrays": 2, //数组中多出逗号
66 | "no-shadow-restricted-names": 2, //关键词与命名冲突
67 | "no-undef": 2, //变量未定义
68 | "no-unused-vars": 0, //变量定义后未使用
69 | "no-cond-assign": 2, //条件语句中禁止赋值操作
70 | "no-native-reassign": 2, //禁止覆盖原生对象
71 |
72 | //代码风格优化
73 | "no-else-return": 1, //在else代码块中return,else是多余的
74 | "no-multi-spaces": 1, //不允许多个空格
75 | "key-spacing": [1, {"beforeColon": false, "afterColon": true}],//object直接量建议写法 : 后一个空格签名不留空格
76 | "block-scoped-var": 1, //变量定义后未使用
77 | "consistent-return": 1, //函数返回值可能是不同类型
78 | "accessor-pairs": 2, //object getter/setter方法需要成对出现
79 | "dot-location": [2, "property"], //换行调用对象方法 点操作符应写在行首
80 | "no-lone-blocks": 0, //多余的{}嵌套
81 | "no-empty-label": 0, //无用的标记
82 | "no-extend-native": 2, //禁止扩展原生对象
83 | "no-floating-decimal": 2, //浮点型需要写全 禁止.1 或 2.写法
84 | "no-loop-func": 2, //禁止在循环体中定义函数
85 | "no-new-func": 2, //禁止new Function(...) 写法
86 | "no-self-compare": 2, //不允与自己比较作为条件
87 | "no-sequences": 2, //禁止可能导致结果不明确的逗号操作符
88 | "no-throw-literal": 2, //禁止抛出一个直接量 应是Error对象
89 | "no-return-assign": [2, "always"], //不允return时有赋值操作
90 | "no-redeclare": [2, {"builtinGlobals": true}],//不允许重复声明
91 | "no-unused-expressions": [2, {"allowShortCircuit": true, "allowTernary": true}],//未使用的表达式
92 | "no-useless-call": 2, //无意义的函数call或apply
93 | "no-useless-concat": 2, //无意义的string concat
94 | "no-void": 2, //禁用void
95 | "no-with": 2, //禁用with
96 | "no-warning-comments": [1, { "terms": ["fixme", "any other term"], "location": "anywhere" }],//标记未写注释
97 | "curly": 2, //if、else、while、for代码块用{}包围
98 | "one-var": 0,
99 | "no-multiple-empty-lines": [1, {"max": 4, "maxEOF": 3}], //空行 最多三行
100 |
101 | //工程化配置
102 | // "prettier.singleQuote": 1, // 防止格式化代码后单引号变双引号
103 | // "update.channel": 1, // 配置是否从更新通道接收自动更新。更改后需要重启。
104 | // "files.autoSaveDelay": 1500, // 保存延时 intellij webstrom 默认制动保存
105 | // "files.autoSave": "afterDelay" // 文件自动保存
106 |
107 | // "eslint.autoFixOnSave": false, // ESLint 自动修复
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 zhoulujun.cn
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack4-vue2-project-template",
3 | "version": "2.0.0",
4 | "description": "webpack4 vue2 sass标准模板工程",
5 | "main": "index.js",
6 | "scripts": {
7 | "dev": "webpack --mode development",
8 | "build": "rm -r dist & webpack --mode production",
9 | "dist": "rm -r dist & webpack --config webpack.build.js",
10 | "analy": "webpack --config webpack.analy.js",
11 | "start": "node webpack.server.js",
12 | "test": "echo \"Error: no test specified\" && exit 1",
13 | "clean": "rm -r dist/*"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/zhoulujun/webpack4-vue2-project-template.git"
18 | },
19 | "keywords": [
20 | "webpack4",
21 | "sass",
22 | "vue2",
23 | "project"
24 | ],
25 | "author": "zhoulujun.cn",
26 | "license": "MIT",
27 | "bugs": {
28 | "url": "https://github.com/zhoulujun/webpack4-vue2-project-template/issues"
29 | },
30 | "homepage": "https://github.com/zhoulujun/webpack4-vue2-project-template#readme",
31 | "devDependencies": {
32 | "@babel/core": "^7.2.2",
33 | "@babel/preset-env": "^7.2.3",
34 | "autoprefixer": "^9.4.4",
35 | "babel-eslint": "^10.0.1",
36 | "babel-loader": "^8.0.4",
37 | "css-loader": "^2.1.0",
38 | "eslint": "^5.12.0",
39 | "eslint-loader": "^2.1.1",
40 | "eslint-plugin-react": "^7.12.3",
41 | "eslint-plugin-vue": "^5.1.0",
42 | "file-loader": "^3.0.1",
43 | "happypack": "^5.0.1",
44 | "html-loader": "^0.5.5",
45 | "html-webpack-plugin": "^3.2.0",
46 | "image-webpack-loader": "^4.6.0",
47 | "less": "^3.9.0",
48 | "less-loader": "^4.1.0",
49 | "mini-css-extract-plugin": "^0.5.0",
50 | "open": "0.0.5",
51 | "postcss": "^7.0.7",
52 | "postcss-loader": "^3.0.0",
53 | "sass.js": "^0.11.0",
54 | "sassjs-loader": "^2.0.0",
55 | "style-loader": "^0.23.1",
56 | "url-loader": "^1.1.2",
57 | "vue": "^2.5.21",
58 | "vue-loader": "^15.4.2",
59 | "vue-router": "^3.0.2",
60 | "vue-style-loader": "^4.1.2",
61 | "vue-template-compiler": "^2.5.21",
62 | "webpack": "^4.28.3",
63 | "webpack-assets-manifest": "^3.1.1",
64 | "webpack-bundle-analyzer": "^3.0.3",
65 | "webpack-cli": "^3.2.0",
66 | "webpack-dev-server": "^3.1.14",
67 | "webpack-sftp-client": "^1.2.1",
68 | "webpack-subresource-integrity": "^1.3.1"
69 | },
70 | "dependencies": {
71 | "sass": "^1.21.0"
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/7/192:59 PM
3 | *@version 1.0.0
4 | */
5 |
6 | /*module.exports = {
7 | plugins: {
8 | 'autoprefixer': {
9 | browsers: [
10 | "> 1%",
11 | "last 5 versions",
12 | "not ie <= 9",
13 | "ios >= 8",
14 | "android >= 4.0"
15 | ]
16 | }
17 | }
18 | };*/
19 |
20 | module.exports = {
21 | plugins: [
22 | require('autoprefixer')({
23 | browsers: [
24 | "> 1%",
25 | "last 105 versions",
26 | "not ie <= 8",
27 | "ios >= 8",
28 | "android >= 4.0"
29 | ]
30 | })
31 | ]
32 | };
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | webpack4 sass babel vue2 标准工程模板
2 | 但是,webpack4还是需要n多优化部分,配置下来,实为不易。而实际开发也不需要浪费这个时间——了解即可
3 | > webpack 一直以来最饱受诟病的就是其配置门槛极高,配置内容极其复杂和繁琐,容易让人从入门到放弃,而它的后起之秀如 rollup、parcel 等均在配置流程上做了极大的优化,做到开箱即用,所以webpack 4 也从中借鉴了不少经验来提升自身的配置效率。愿世间再也不需要 webpack 配置工程师。
4 |
5 |
6 | 目前node-sass sass-loader 替换为 sass.js 与sassjs-loader 免除node-sass 安装困难的烦恼
7 |
8 |
9 | 启动:
10 | ```bash
11 | npm run start
12 | ```
13 | 打包:
14 | ```bash
15 | npm run build
16 | ```
17 |
18 |
19 |
20 |
21 |
22 | # 目录结构
23 |
24 | # 团队规范
25 | 遵从平台发布前端规范标准,节选以下要点:
26 |
27 | ## 命名规范
28 | 遵从Camel命名
29 |
30 | ### 变量命名规范:
31 |
32 | #### js规范,请遵从eslint
33 | + 常量全部大写,单词间下划线分隔
34 | + 类采用Pascal命名
35 | ### scss 规范
36 | + css 按照工程结构 嵌套书写,嵌套层级不超过三层——采用 @at-root
37 | + 非页面引用scss文件,加前缀 _ 如:_fun.scss _mixin.scss
38 |
39 | # 构建过程 节选关键步骤
40 | ### 构建目录初始化
41 | ```bash
42 | mkdir yourFileName
43 | cd yourFileName
44 | ```
45 | 根据工程目录结构,构建相关文件
46 | ……
47 | ___
48 | ```bash
49 | npm init
50 | npm install webpack webpack-cli --save-dev
51 | ```
52 | ##### 注:--save-dev和--save的区别:
53 | development很明显就是我们开发所需要的依赖包,而打包好上线的话是不需要这些包的,一来各种包加起来太大,二来它只是我们开发提高效率的工具而已;
54 | 由于本工程只在本地跑,最终还是sftp自动dist 到服务器,所以暂略
55 |
56 | 修改package.json ,npm run dev 检查打包结果
57 | ```json
58 | {
59 | "scripts": {
60 | "dev": "webpack --mode development",
61 | "build": "webpack --mode production"
62 | }
63 | }
64 | ```
65 | ##### 注:webpack4只需要一个--mode选项 指定 production||development
66 | 参考http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html
67 | +如果是并行执行(即同时的平行执行),可以使用&符号。
68 | +如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&符号。
69 | npm run script1.js & npm run script2.js
70 | npm run script1.js && npm run script2.js
71 |
72 |
73 | ___
74 | #### 配置webpack配置文件 webpack.config.js
75 | ##### rule对象参数说明
76 | + test: A condition that must be met 必须满足的条件
77 | + exclude: A condition that must not be met 不能满足的条件
78 | + include: A condition that must be met 必须满足的条件
79 | + loader: A string of “!” separated loaders 用 “!”分割loaders
80 | + loaders: An array of loaders as string loaders的字符串数组
81 |
82 | #### 基础loader
83 |
84 | ```bash
85 | npm install css-loader style-loader html-loader url-loader file-loader --save-dev
86 | ```
87 |
88 | ```javascript
89 | [
90 | {
91 | test: /\.html$/,
92 | use: 'html-loader'
93 | },
94 | {
95 | test: /\.css$/,
96 | use: [
97 | {
98 | loader: 'style-loader',
99 | options:{
100 | // singleton:true //处理为单个style标签
101 | }
102 | },
103 | {
104 | loader: 'css-loader',
105 | options:{
106 | // minimize:true //压缩css
107 | }
108 | }
109 | ]
110 | },
111 | {
112 | test:/\.(png|jpg|jpeg|gif)$/,//图片处理
113 | use:[
114 | {
115 | loader: 'url-loader',
116 | options:{
117 | limit:2048,
118 | name:'[name][hash].[ext]'
119 | }
120 | },
121 | {
122 | loader: 'file-loader',
123 | publicPath:publicPath,
124 | outputPath: 'dist/',
125 | useRelativePath: true
126 | }
127 | ]
128 | },
129 | {
130 | test: /\.(woff|woff2|eot|ttf|otf)$/,//字体处理
131 | use: ['url-loader']
132 | },
133 |
134 | ]
135 | ```
136 | #### 配置babel 编译js
137 | ```bash
138 | npm install --save-dev babel-loader @babel/core @babel/preset-env
139 | ```
140 |
141 | ```javascript
142 | [
143 | {
144 | test: /\.js$/,
145 | loader: 'babel-loader',
146 | exclude: /node_modules/ //设置node_modules里的js文件不用解析
147 | }
148 | ]
149 | ```
150 |
151 | 参考:https://segmentfault.com/a/1190000010468759
152 |
153 | babel7.0后,需要@ @babel/core vs babel-core babel插件和版本需要对应上,不然掉坑
154 | 参考https://www.w3ctech.com/topic/2150
155 | babel-preset-es2015 babel-plugin-transform-runtime babel-plugin-add-module-exports babel-plugin-transform-runtime babel-plugin-transform-class-properties
156 |
157 | #### 配置eslint 检查
158 |
159 | ```bash
160 | npm install --save-dev eslint eslint-loader babel-eslint eslint-plugin-react eslint-plugin-vue
161 | ```
162 |
163 | ```javascript
164 | [
165 | {//eslint 检查
166 | test: /\.(js|jsx)$/,
167 | enforce: 'pre',
168 | loader: ['eslint-loader'],
169 | exclude: /node_modules/ //设置node_modules里的js文件不用解析
170 | },
171 | ]
172 | ```
173 | 增加.eslintrc配置
174 | ##### 其实没有多大必要,intellij 会自动检车eslint
175 |
176 | #### 处理html
177 | npm install html-webpack-plugin
178 | ```javascript
179 | new HtmlWebpackPlugin({
180 | filename: './index.html',//输出文件
181 | template: 'src/index.html',//模板文件
182 | inject: 'body',//插入位置
183 | chunks: ['index'],
184 | hash: true,
185 | minify: {
186 | caseSensitive:false,
187 | removeComment:true,//移除注释
188 | collapseWhitespace:false//移除多余空格
189 | }
190 | })
191 | ```
192 | #### 处理图片 - 压缩图片
193 | 参考:http://shirmy.me/2018/05/15/webpack-图片、文件处理/
194 | ```bash
195 | npm install image-webpack-loader --save-dev
196 | ```
197 |
198 | ```javascript
199 | [
200 | {
201 | test: /\.(png|jpg|jpeg|gif)$/i,//图片处理
202 | use: [
203 | {
204 | loader: 'url-loader',
205 | options: {
206 | limit: 0,//图片不转base64,增加css的阻塞时间,开启http2,所以也不用雪碧图
207 | name: '[name].[hash:5].[ext]',
208 | }
209 | },
210 | ]
211 | },
212 | {//压缩图片
213 | loader: 'image-webpack-loader',
214 | options: {
215 | bypassOnDebug: true,
216 | }
217 | },
218 | ]
219 | ```
220 |
221 |
222 |
223 | #### 配置webapck server
224 | ```bash
225 | npm install webpack-dev-server open --save-dev
226 | ```
227 | 参看 webpack.server.js 注释
228 |
229 | "start": "node webpack.server.js",
230 | npm start 启动项目
231 |
232 | ### 配置css优化设置
233 |
234 | ```bash
235 | npm install --save-dev postcss-loader autoprefixer postcss autoprefixer mini-css-extract-plugin
236 | ```
237 | ##### 注:
238 | + webpack4已经废弃 extract-text-webpack-plugin 这个插件了,现在使用的是 mini-css-extract-plugin
239 | + 在项目根目录新建postcss.config.js文件,并对postcss进行配置:
240 | ```javascript
241 | module.exports = {
242 | plugins: {
243 | 'autoprefixer': {
244 | browsers: [
245 | "> 1%",
246 | "last 5 versions",
247 | "not ie <= 9",
248 | "ios >= 8",
249 | "android >= 4.0"
250 | ]
251 | }
252 | }
253 | };
254 | ```
255 | 不然会报出:Error: No PostCSS Config found
256 |
257 | #### 自动消除冗余的css代码
258 | ```bash
259 | npm install --save-dev optimize-css-assets-webpack-plugin
260 | ```
261 | ##### 个人觉得css压缩优化空间不大,nginx开启gzip的情况,很有限,有点画蛇添足
262 | #### 配置sass
263 | ```bash
264 | npm install --save-dev node-sass sass-loader
265 |
266 | ```
267 | 但是node-sass 是个坑货
268 | 所以最好换位
269 | ```bash
270 | $ npm install --save-dev sassjs-loader sass.js
271 |
272 | ```
273 | https://www.npmjs.com/package/sass
274 |
275 | https://www.npmjs.com/package/sassjs-loader
276 |
277 |
278 | ## webpack构建优化
279 |
280 | #### 多线程 happypack
281 |
282 | ```bash
283 | npm install --save-dev happypack
284 |
285 | ```
286 |
287 | 配置第三方包,比如jquery
288 | ```bash
289 | npm install imports-loader --save-dev
290 | ```
291 | ```javascript
292 | [
293 | {
294 | loader: 'imports-loader',
295 | options: {
296 | // 模块为 value,同样webpack也会解析它,如果没有则从alias中解析它
297 | $: 'jquery'
298 | }
299 | }
300 | ]
301 | ```
302 | #### 增加manifest.json 配置,缓存校对下载, 增加js integrity 安全校验
303 | ```bash
304 | npm install --save-dev webpack-subresource-integrity webpack-assets-manifest
305 | ```
306 | 两个插件准备写成一个,看来不到春节没有时间
307 |
308 |
309 | #### 增加webpack 模块分析
310 | ```bash
311 | npm install --save-dev webpack-bundle-analyzer
312 | ```
313 | 配置参看 webpack.analy
314 | 参考文章:https://www.cnblogs.com/ssh-007/p/7944491.html
315 |
316 | #### 增加上传至服务器
317 | ```bash
318 | npm install --save-dev webpack-sftp-client
319 | ```
320 |
321 |
322 |
323 |
324 |
325 | #### 配置vue
326 | ```bash
327 | npm install --save-dev vue vue-router vue-loader vue-template-compiler vue-style-loader
328 | ```
329 |
330 | ```javascript
331 | [
332 | {
333 | test: /\.vue$/,
334 | use: 'vue-loader'
335 | },
336 | ]
337 | ```
338 |
339 |
340 |
341 |
342 |
343 | webpack 相关优化,可参看:https://www.zhoulujun.cn/html/tools/webpack/2016_0218_7492.html
344 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |