├── .babelrc
├── src
├── images
│ └── logo_my.png
├── router
│ └── router.js
├── index.js
├── index.html
├── style
│ └── index.scss
└── App.vue
├── .editorconfig
├── webpack.analy.js
├── postcss.config.js
├── LICENSE
├── webpack.server.js
├── webpack.build.js
├── package.json
├── .eslintrc
├── webpack.config.js
└── readme.md
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"]
3 | }
--------------------------------------------------------------------------------
/src/images/logo_my.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhoulujun/webpack4-vue2-project-template/HEAD/src/images/logo_my.png
--------------------------------------------------------------------------------
/src/router/router.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/7/196:05 PM
3 | *@version 1.0.0
4 | */
5 | import App from '../App.vue';
6 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/4/1910:30 AM
3 | *@version 1.0.0
4 | */
5 | import "./style/index.scss";
6 |
7 | import Vue from 'vue/dist/vue.common';//这是个坑 非:'vue'
8 | import App from './App';
9 | new Vue({
10 | el:'#app',
11 | render:h=>h(App)
12 | });
--------------------------------------------------------------------------------
/webpack.analy.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/4/1910:30 AM
3 | *@version 1.0.0
4 | *webpack 打包配置
5 | *打包速度方面优化无必要。可能你研究了半天,改了一堆参数发现其实也就提升了几秒,但维护成本上去了,得不偿失。
6 | */
7 |
8 |
9 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
10 |
11 | const config = require('./webpack.config');
12 |
13 | config.plugins.push(
14 | new BundleAnalyzerPlugin()
15 |
16 | );
17 |
18 | module.exports = config;
19 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | webpack4-vue2-project-template
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/style/index.scss:
--------------------------------------------------------------------------------
1 | .demo{
2 | width: 146px;
3 | height: 49px;
4 | background: url("../images/logo_my.png");
5 | background-size: 100%;
6 | transform-origin: 100%;
7 | transform: scale(.5);
8 | display: -webkit-box;
9 |
10 | }
11 |
12 | .page {
13 | display: grid;
14 | grid-gap: 33px;
15 | grid-template:
16 | "head head head" 1fr
17 | "nav main main" minmax(100px, 1fr)
18 | "nav foot foot" 2fr /
19 | 1fr 100px 1fr;
20 | }
21 | .page__head {
22 | grid-area: head;
23 | }
24 | .page__nav {
25 | grid-area: nav;
26 | }
27 | .page__main {
28 | grid-area: main;
29 | }
30 | .page__footer {
31 | grid-area: foot;
32 | }
--------------------------------------------------------------------------------
/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 | };
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
testHello
4 |
5 |
6 |
7 |
8 |
9 |
28 |
29 |
32 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/webpack.server.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/4/1910:30 AM
3 | *@version 1.0.0
4 | * webpack server 配置
5 | */
6 | const webpack = require('webpack');
7 | const WebpackDevServer = require('webpack-dev-server');
8 | const open = require('open');
9 |
10 | const config = require('./webpack.config');
11 |
12 | process.env.NODE_ENV='development';
13 | config.mode = 'development';
14 | config.devtool='cheap-module-eval-source-map';
15 |
16 | config.plugins.push(
17 | new webpack.HotModuleReplacementPlugin(),//热替换
18 | new webpack.NoEmitOnErrorsPlugin(),//去除系统抛出的错误消息
19 | );
20 |
21 |
22 | const addressObj = {
23 | ip: getLocalIPAdress(),
24 | port: 11036
25 | };
26 |
27 | new WebpackDevServer(webpack(config), {
28 |
29 | historyApiFallback: true,
30 | hot: true,//热加载
31 | hotOnly: true,
32 | overlay: {
33 | errors: true//webpack编译出现的错误是否会出现在网页中
34 | },
35 | compress: false,
36 | proxy: {
37 | '/api/*': {
38 | target: 'https://zhoulujun.cn/api',//代理地址
39 | secure: false
40 | }
41 | }
42 | })
43 | .listen(addressObj.port,addressObj.ip,function (error) {
44 | error&&console.log(error);
45 | let address=`http://${addressObj.ip}:${addressObj.port}`;
46 | // let address=`http://localhost:13080`;
47 | open(address);
48 | console.log('listening at:'+address)
49 | });
50 |
51 | function getLocalIPAdress () {
52 | var interfaces = require('os').networkInterfaces();
53 | for (let devName in interfaces) {
54 | let iface = interfaces[devName];
55 | for (let i = 0; i < iface.length; i++) {
56 | let alias = iface[i];
57 | if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
58 | return alias.address;
59 | }
60 | }
61 | }
62 | return 'localhost';
63 | }
64 |
--------------------------------------------------------------------------------
/webpack.build.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/4/1910:30 AM
3 | *@version 1.0.0
4 | *webpack 打包配置
5 | *打包速度方面优化无必要。可能你研究了半天,改了一堆参数发现其实也就提升了几秒,但维护成本上去了,得不偿失。
6 | */
7 |
8 |
9 | // const ManifestPlugin = require('webpack-manifest-plugin');
10 | const WebpackAssetsManifest = require('webpack-assets-manifest');
11 | const WebpackSubresourceIntegrity = require('webpack-subresource-integrity');
12 | const WebpackSftpClient = require('webpack-sftp-client');
13 |
14 |
15 | const config = require('./webpack.config');
16 |
17 | process.env.NODE_ENV = 'production';
18 | config.mode = 'production';
19 | // config.output.publicPath='http://zhoulujun.cn/demo/';
20 |
21 | config.optimization = {
22 | splitChunks: { // 打包 node_modules里的代码
23 | chunks: 'initial', // 只对入口文件处理
24 | cacheGroups: {
25 | commons: {
26 | chunks: 'initial',//打包初始时依赖第三方
27 | name:'commons',
28 | minChunks: 2,//最小共用次数
29 | maxInitialRequests: 5,
30 | minSize: 0
31 | },
32 | vendor: { // split `node_modules`目录下被打包的代码到 `page/vendor.js && .css` 没找到可打包文件的话,则没有。
33 | test: /node_modules/,
34 | chunks: 'initial',
35 | name: 'vendor',
36 | priority: 10,
37 | enforce: true
38 | }
39 | }
40 | },
41 | runtimeChunk: {name:'runtime'}// 单独抽离 runtimeChunk 之后,每次打包都会生成一个runtimeChunk.xxx.js。
42 | };
43 |
44 | config.plugins.push(
45 | new WebpackAssetsManifest({
46 | // Options go here
47 | integrity: true,
48 | integrityHashes: ['sha256', 'sha384']
49 | }),
50 | new WebpackSubresourceIntegrity({
51 | hashFuncNames: ['sha256', 'sha384']
52 | }),
53 |
54 | /*new webpack.optimize.UglifyJsPlugin(),
55 | new webpack.optimize.OccurenceOrderPlugin(),
56 | new webpack.optimize.AggressiveMergingPlugin(),
57 | new webpack.NoErrorsPlugin()*/
58 |
59 | //上传到服务器发布
60 | /*new WebpackSftpClient({
61 | port: '20020',
62 | host: '10.111.111.38',
63 | username: 'nginx',
64 | password: 'zlj@123',
65 | path: './dist/',//本地上传目录
66 | remotePath: '/usr/local/nginx/html/demo',//服务器目标目录
67 | verbose: true
68 | })*/
69 | );
70 |
71 | module.exports = config;
72 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | *@author Create by zhoulujun.cn on 1/4/1910:30 AM
3 | *@version 1.0.0
4 | * webpack 配置文件
5 | */
6 | 'use strict';
7 | const path = require('path');
8 | const os = require('os');
9 | const HappyPack = require('happypack');
10 | const HtmlWebpackPlugin = require('html-webpack-plugin');
11 | const {VueLoaderPlugin} = require('vue-loader');
12 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
13 | const devMode = process.env.NODE_ENV === 'development';
14 | const happyThreadPool = HappyPack.ThreadPool({size: os.cpus().length});
15 | const publicPath = '';
16 | console.log('devMode___________', devMode);
17 | const config = {
18 | // target: 'web',//告知 webpack 为目标(target)指定一个环境。默认web
19 | entry: {//配置页面入口
20 | index: './src/index.js'
21 | },
22 | output: { //配置输出选项
23 | path: path.resolve(__dirname, 'dist'),//输出路径为,当前路径下
24 | filename: '[name].[hash:5].js'//输出后的文件名称
25 | },
26 | resolve: {
27 | extensions: ['.js', '.json', '.vue'] //减少文件查找
28 | },
29 |
30 | module: {
31 | rules: [
32 | {
33 | test: /\.html$/,
34 | use: 'html-loader'
35 | },
36 | {
37 | test: /\.css$/,
38 | use: [//使用use可配置多个loader进行处理。顺序由最后一个至第一个。此处匹配到css文件后,先由postcss-loader处理,css-loader处理后再交由style-loader处理
39 | 'vue-style-loader',//将样式通过style标签的方式加入到dom中
40 | devMode ? {
41 | loader: 'style-loader',
42 | options: {
43 | // singleton:true //处理为单个style标签
44 | }
45 | } :
46 | MiniCssExtractPlugin.loader,
47 | {//css-loader 解释(interpret) @import 和 url()
48 | loader: 'css-loader',
49 | options: {
50 | // url:false, //false css中加载图片的路径将不会被解析 不会改变
51 | // minimize:true, //压缩css
52 | importLoaders: 1//importLoaders代表import进来的资源;2代表css-loader后还需要使用几个loader
53 | }
54 | },
55 | {//需在css-loader/style-loader后面,在其他预处理前面
56 | loader: 'postcss-loader',
57 | options: {
58 |
59 | plugins: [
60 | require('autoprefixer')
61 | ],
62 | browsers: [
63 | '> 1%',
64 | 'last 5 versions',
65 | 'not ie <= 9',
66 | 'ios >= 8',
67 | 'android >= 4.0'
68 | ]
69 | }
70 | }
71 | ]
72 | },
73 | { //sass文件。vue中会将使用sass写的样式抛出给该rule处理.vue中lang可以设置为sass/scss,只需将两者类型都匹配到sass就行
74 | test: /\.(scss)$/,
75 | use: [//使用use可配置多个loader进行处理。顺序由最后一个至第一个。此处匹配到css文件后,先由css-loader进行处理,css-loader处理后再交由vue-style-loader处理
76 | 'vue-style-loader',//将样式通过style标签的方式加入到dom中
77 | devMode ? {
78 | loader: 'style-loader'
79 | /* options: {
80 | singleton:true //处理为单个style标签
81 | }*/
82 | } :
83 | MiniCssExtractPlugin.loader,
84 | {//css-loader 解释(interpret) @import 和 url()
85 | loader: 'css-loader',
86 | options: {
87 | // url:false, //false css中加载图片的路径将不会被解析 不会改变
88 | // minimize:true, //压缩css
89 | importLoaders: 1,
90 | sourceMap: devMode//importLoaders代表import进来的资源;2代表css-loader后还需要使用几个loader
91 | }
92 | },
93 | {//需在css-loader/style-loader后面,在其他预处理前面
94 | loader: 'postcss-loader',
95 | options: {
96 |
97 | plugins: [
98 | require('autoprefixer')
99 | ],
100 | browsers: [
101 | '> 1%',
102 | 'last 5 versions',
103 | 'not ie <= 9',
104 | 'ios >= 8',
105 | 'android >= 4.0'
106 | ],
107 | sourceMap: devMode
108 | }
109 | },
110 | {
111 | loader: 'sassjs-loader'
112 |
113 | }
114 | ]
115 | },
116 | { //less。vue中会将使用sass写的样式抛出给该rule处理.vue中lang可以设置为sass/scss,只需将两者类型都匹配到sass就行
117 | test: /\.(less)$/,
118 | use: [//使用use可配置多个loader进行处理。顺序由最后一个至第一个。此处匹配到css文件后,先由css-loader进行处理,css-loader处理后再交由vue-style-loader处理
119 | 'vue-style-loader',//将样式通过style标签的方式加入到dom中
120 | 'style-loader'
121 | ]
122 | },
123 |
124 | {
125 | test: /\.(png|jpg|jpeg|gif)$/,//图片处理
126 | use: [
127 | {
128 | loader: 'url-loader',
129 | options: {
130 | limit: 50,//图片不转base64,减少css的阻塞时间,开启http2,所以也不用雪碧图
131 | name: '[name].[hash:5].[ext]',
132 | url: false,//不处理css图片路径,
133 | outputPath: 'images'
134 | }
135 | }
136 | ]
137 | },
138 |
139 | {//压缩图片
140 | loader: 'image-webpack-loader',
141 | options: {
142 | bypassOnDebug: true
143 | }
144 | },
145 | {
146 | test: /\.(woff|woff2|eot|ttf|otf)$/,//字体处理
147 | use: ['url-loader']
148 | },
149 |
150 | {//babel编译
151 | test: /\.js$/,
152 | loader: ['happypack/loader?id=js'],
153 | exclude: /node_modules/ //设置node_modules里的js文件不用解析
154 | },
155 |
156 | {//eslint 检查
157 | test: /\.(js|jsx)$/,
158 | enforce: 'pre',
159 | loader: ['eslint-loader'],
160 | exclude: /node_modules/ //设置node_modules里的js文件不用解析
161 | },
162 | {
163 | test: /\.vue$/,
164 | loader: 'vue-loader'
165 | }
166 |
167 | ]
168 | },
169 | plugins: [
170 |
171 | new HappyPack({
172 | id: 'js',//用id来标识 happypack处理那里类文件
173 | threadPool: happyThreadPool, //共享进程池
174 | loaders: [
175 | {
176 | loader: 'babel-loader'
177 | }
178 | ]
179 | }),
180 | new HappyPack({
181 | id: 'scss',//用id来标识 happypack处理那里类文件
182 | threadPool: happyThreadPool, //共享进程池
183 | loaders: [
184 | {
185 | loader: 'sassjs-loader'
186 | }
187 | ]
188 | }),
189 | new HappyPack({
190 | id: 'less',//用id来标识 happypack处理那里类文件
191 | threadPool: happyThreadPool, //共享进程池
192 | loaders: [
193 | {
194 | loader: 'less-loader'
195 | }
196 | ]
197 | }),
198 |
199 | new VueLoaderPlugin(),
200 |
201 | new MiniCssExtractPlugin({
202 | filename: '[name].[hash:5].css',
203 | chunkFilename: '[id].[hash].css',
204 | disable: false, //是否禁用此插件
205 | allChunks: true
206 | }),
207 |
208 | new HtmlWebpackPlugin({
209 | template: './src/index.html',//本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等),如比如 handlebars!src/index.hbs;
210 | filename: './index.html',//输出文件的文件名称,默认为index.html,不配置就是该文件名;此外,还可以为输出文件指定目录位置(例如'html/index.html')
211 | chunks: ['index','vendor','commons','manifest'],
212 | inject: true,//1、true或者body:所有JavaScript资源插入到body元素的底部2、head: 所有JavaScript资源插入到head元素中3、false: 所有静态资源css和JavaScript都不会注入到模板文件中
213 | showErrors: true,//是否将错误信息输出到html页面中
214 | hash: false,//是否为所有注入的静态资源添加webpack每次编译产生的唯一hash值
215 | favicon: '',//添加特定的 favicon 路径到输出的 HTML 文件中。
216 | minify: {
217 | caseSensitive: false,
218 | removeComment: true,//移除注释
219 | collapseWhitespace: false//移除多余空格
220 | }
221 | })
222 | ]
223 | };
224 |
225 | module.exports = config;
226 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------