├── src
├── style
│ └── common
│ │ ├── less
│ │ ├── base.less
│ │ ├── README.md
│ │ ├── _utils.less
│ │ └── _mixin.less
│ │ └── scss
│ │ ├── base.scss
│ │ ├── _utils.scss
│ │ └── _mixin.scss
├── assets
│ └── favicon
│ │ └── favicon.ico
├── index.ts
├── test.ts
├── style.less
└── exp.ts
├── .gitignore
├── .gitattributes
├── tsconfig.json
├── .babelrc
├── webpack.dev.js
├── README.md
├── index.html
├── webpack.config.js
├── package.json
├── webpack.prod.js
└── webpack.common.js
/src/style/common/less/base.less:
--------------------------------------------------------------------------------
1 | @import "./_utils.less";
--------------------------------------------------------------------------------
/src/style/common/less/README.md:
--------------------------------------------------------------------------------
1 | 这里是less的通用样式,mixin,和一些方法,同scss
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
--------------------------------------------------------------------------------
/src/assets/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IFmiss/webpack-tpl/master/src/assets/favicon/favicon.ico
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.js linguist-language=javascript
2 | *.css linguist-language=javascript
3 | *.html linguist-language=javascript
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import '@/style.less';
2 | import Dutils from 'd-utils';
3 | Dutils.LogUtils.logInfo('WEBPACK-TPL', 'HELLO')
4 |
--------------------------------------------------------------------------------
/src/style/common/scss/base.scss:
--------------------------------------------------------------------------------
1 | @import "node_modules/compass-mixins/lib/compass/css3";
2 | @import './_utils';
3 | @import './_mixin';
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "./dist/",
4 | "sourceMap": true,
5 | "noImplicitAny": true,
6 | "module": "commonjs",
7 | "target": "es5",
8 | "jsx": "react",
9 | "allowJs": true
10 | }
11 | }
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | class Shape {
2 | area: number;
3 | color: string;
4 | constructor ( name: string, width: number, height: number ) {
5 | this.area = width * height;
6 | this.color = "pink";
7 | };
8 |
9 | shoutout() {
10 | return "I'm " + this.color + " with an area of " + this.area + " cm squared.";
11 | }
12 | }
13 |
14 | var square = new Shape("square", 30, 30);
15 | console.log( square.shoutout() );
16 | console.log( 'Area of Shape: ' + square.area );
17 | console.log( 'Color of Shape: ' + square.color );
18 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", {
4 | "modules": "false",
5 | }],
6 | ],
7 | "plugins":[
8 | ["@babel/plugin-proposal-decorators", { "legacy": true }],
9 | ["@babel/plugin-proposal-class-properties", { "loose" : true }],
10 | [
11 | "@babel/plugin-transform-runtime",
12 | {
13 | "absoluteRuntime": false,
14 | "corejs": false,
15 | "helpers": true,
16 | "regenerator": true,
17 | "useESModules": false
18 | }
19 | ]
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 | const webpackPromptPlugin = require('@dw/webpack-prompt-plugin')
4 |
5 | module.exports = merge(common, {
6 | devtool: 'inline-source-map',
7 | plugins: [
8 | new webpackPromptPlugin()
9 | ],
10 | devServer: {
11 | // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html。通过传入以下启用:
12 | contentBase: "./",
13 | host: '0.0.0.0',
14 | // 端口号
15 | port: 2006,
16 | //当有编译器错误或警告时,在浏览器中显示全屏覆盖。默认禁用。如果您只想显示编译器错误:
17 | noInfo: true,
18 | // 配置端口号
19 | overlay: true,
20 | }
21 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # webpack-tpl
2 |
3 |  
4 |    
5 |
6 | 一个通用的webpack模板,配置基本的内容,可满足项目的基本的使用
7 | - less, sass, stylus支持
8 | - d-utils-js通用js的支持
9 | - webpack版本4.0+, 支持热更新
10 | - 支持typescript
11 |
12 | 
13 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | webpack
6 |
7 |
8 |
9 | Webpack 通用模板
10 | 基于wenpack 4.0
11 | 配置d-js-utils通用方法
12 | 支持 less(sass, stylus需自行安装依赖)
13 | 支持 typescript
14 |
15 |
16 |
17 | 未曾遗忘的青春
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/style.less:
--------------------------------------------------------------------------------
1 | @import "./style/common/less/base.less";
2 | body,html{
3 | margin: 0;
4 | padding: 0;
5 | height:100%;
6 | background: #111010;
7 | }
8 | body{
9 | // background: red;
10 | display: flex;
11 | width: 100%;
12 | height: 100%;
13 | align-items: center;
14 | justify-content: center;
15 | flex-direction: column;
16 | .title{
17 | font-size: 42px;
18 | .colortext-l(#4facfe, #00f2fe);
19 | display: inline-block;
20 | margin-top: 0;
21 | }
22 | .disc{
23 | font-size: 14px;
24 | padding: 6px 0;
25 | color: #f1f1f1;
26 | }
27 | .github-info{
28 | margin-top: 40px;
29 | text-align: center;
30 | display: flex;
31 | justify-content: center;
32 | span{
33 | color: #fff;
34 | font: 14px;
35 | font-size:14px;
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/src/style/common/less/_utils.less:
--------------------------------------------------------------------------------
1 | @import "./_mixin.less";
2 | // 浮动
3 | .right{
4 | float: right;
5 | }
6 |
7 | .left{
8 | float: left;
9 | }
10 |
11 | .center{
12 | margin: 0 auto;
13 | float: none;
14 | }
15 |
16 | // 清除浮动
17 | .clear-both{
18 | clear: both;
19 | height:1px;
20 | margin-top:-1px;
21 | overflow:hidden;
22 | &:before{
23 | display:none;
24 | }
25 | &:after{
26 | display:none;
27 | }
28 | }
29 |
30 | .block_area{
31 | margin: 0 auto;
32 | position: relative;
33 | font-size: 14px;
34 | }
35 |
36 | // inline-block对齐 或者文本对齐
37 | .text-left{
38 | text-align:left;
39 | }
40 |
41 | .text-right{
42 | text-align:right;
43 | }
44 |
45 | .text-center{
46 | text-align:center;
47 | }
48 |
49 | .text-bold{
50 | font-weight:bold;
51 | }
52 |
53 | .activeB{
54 | display: block;
55 | }
56 |
57 | .activeF{
58 | display: flex;
59 | }
60 |
61 | .activeN{
62 | display:none;
63 | }
64 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const dev = require('./webpack.dev')
2 | const prod = require('./webpack.prod')
3 | const chalk = require('chalk');
4 | var os = require('os');
5 |
6 | switch (process.env.NODE_ENV) {
7 | case 'development':
8 | module.exports = dev
9 | break
10 | case 'production':
11 | module.exports = prod
12 | break
13 | }
14 |
15 | // 获取Ip
16 | function getIPAdress() {
17 | let localIPAddress = "";
18 | let interfaces = os.networkInterfaces();
19 | for (let devName in interfaces) {
20 | let iface = interfaces[devName];
21 | for (let i = 0; i < iface.length; i++) {
22 | let alias = iface[i];
23 | if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
24 | localIPAddress = alias.address;
25 | }
26 | }
27 | }
28 | localIp = localIPAddress;
29 | return localIPAddress;
30 | }
31 |
32 | // 打印返回信息
33 | // if (process.env.NODE_ENV === 'development') {
34 | // let host = dev.devServer.host ? dev.devServer.host : 'localhost'
35 | // // getIPAdress
36 | // if (host === '0.0.0.0') host = getIPAdress()
37 | // const text = `server will start at: http://${host}:${dev.devServer.port}`
38 | // console.log(chalk.green(text))
39 | // }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-tpl",
3 | "version": "1.0.0",
4 | "description": "webpack-tpl",
5 | "main": "webpack.config.js",
6 | "dependencies": {
7 | "@dw/webpack-prompt-plugin": "^1.0.8",
8 | "autodll-webpack-plugin": "^0.4.2",
9 | "cache-loader": "^4.1.0",
10 | "d-utils": "^3.0.0",
11 | "extract-text-webpack-plugin": "^4.0.0-beta.0",
12 | "happypack": "^5.0.1",
13 | "sha1": "^1.1.1"
14 | },
15 | "scripts": {
16 | "test": "echo \"Error: no test specified\" && exit 1",
17 | "build": "cross-env NODE_ENV=production webpack --progress --profile --mode production",
18 | "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --progress --colors",
19 | "watch": "webpack --colors --watch"
20 | },
21 | "keywords": [
22 | "webpack",
23 | "webpack template",
24 | "template",
25 | "config"
26 | ],
27 | "author": "daiwei",
28 | "license": "ISC",
29 | "devDependencies": {
30 | "@babel/core": "^7.4.3",
31 | "@babel/plugin-proposal-class-properties": "^7.4.0",
32 | "@babel/plugin-proposal-decorators": "^7.4.0",
33 | "@babel/plugin-transform-runtime": "^7.4.3",
34 | "@babel/preset-env": "^7.4.3",
35 | "@babel/runtime": "^7.4.3",
36 | "@types/node": "^11.13.2",
37 | "atob": ">=2.1.0",
38 | "babel-loader": "^8.0.5",
39 | "babel-polyfill": "^6.26.0",
40 | "clean-webpack-plugin": "^1.0.0",
41 | "compass-mixins": "^0.12.10",
42 | "cross-env": "^5.2.0",
43 | "css-loader": "^0.28.10",
44 | "deep-extend": ">=0.5.1",
45 | "html-webpack-plugin": "^3.0.6",
46 | "less": "^3.9.0",
47 | "less-loader": "^4.1.0",
48 | "mini-css-extract-plugin": "^0.5.0",
49 | "optimize-css-assets-webpack-plugin": "^5.0.1",
50 | "postcss-loader": "^3.0.0",
51 | "randomatic": ">=3.0.0",
52 | "style-loader": "^0.20.3",
53 | "ts-loader": "^6.2.1",
54 | "typescript": "^3.2.4",
55 | "uglifyjs-webpack-plugin": "^2.1.1",
56 | "url-loader": "^1.0.1",
57 | "url-parse": ">=1.4.3",
58 | "webpack": "^4.29.0",
59 | "webpack-cli": "^3.2.1",
60 | "webpack-dev-server": ">=3.1.11",
61 | "webpack-merge": "^4.2.1"
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const path = require('path');
3 | const common = require('./webpack.common.js');
4 | const HappyPack = require('happypack')
5 | const AutoDllPlugin = require('autodll-webpack-plugin')
6 | // css压缩打包相关
7 | var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
8 |
9 | // 打包清除dist目录
10 | const CleanWebpackPlugin = require('clean-webpack-plugin');
11 |
12 | const resolve = function (dir) {
13 | return path.resolve(__dirname, dir);
14 | }
15 | module.exports = merge(common, {
16 | entry: {
17 | app: './src/index.ts'
18 | },
19 | output: {
20 | path: resolve('dist'),
21 | publicPath: '',
22 | filename: '[name]-[hash].js'
23 | },
24 | module: {
25 | rules: [
26 | {
27 | test: /\.js$/,
28 | use: [
29 | 'happypack/loader?id=js'
30 | ]
31 | },
32 | {
33 | test: /\.ts$/,
34 | use: [
35 | 'happypack/loader?id=js',
36 | 'happypack/loader?id=ts'
37 | ]
38 | },
39 | ],
40 | },
41 | plugins: [
42 | // 清除
43 | new CleanWebpackPlugin(['dist'], {
44 | verbose: false
45 | }),
46 |
47 | // css 压缩
48 | new OptimizeCssAssetsPlugin({
49 | assetNameRegExp: /\.optimize\.css$/g,
50 | cssProcessor: require('cssnano'),
51 | cssProcessorPluginOptions: {
52 | preset: ['default', { discardComments: { removeAll: true } }],
53 | },
54 | canPrint: true
55 | }),
56 |
57 | // happyPack
58 | new HappyPack({
59 | id: 'js',
60 | loaders: [
61 | 'cache-loader',
62 | {
63 | loader: 'babel-loader',
64 | options: {
65 | presets: ["@babel/preset-env"],
66 | cacheDirectory: true,
67 | },
68 | exclude: /node_modules/,
69 | }
70 | ],
71 | verbose: true,
72 | }),
73 |
74 | new HappyPack({
75 | id: 'ts',
76 | loaders: [
77 | 'cache-loader',
78 | "ts-loader?" + JSON.stringify({happyPackMode: true})
79 | ],
80 | verbose: true,
81 | }),
82 |
83 | new AutoDllPlugin({
84 | inject: true,
85 | filename: '[name][hash:8].js',
86 | entry: {
87 | vendor: [
88 | 'd-utils'
89 | ]
90 | }
91 | })
92 | ]
93 | });
--------------------------------------------------------------------------------
/src/style/common/scss/_utils.scss:
--------------------------------------------------------------------------------
1 | // 浮动
2 | .right{
3 | float: right;
4 | }
5 |
6 | .left{
7 | float: left;
8 | }
9 |
10 | .center{
11 | margin: 0 auto;
12 | float: none;
13 | }
14 |
15 | // 清除浮动
16 | .clear-both{
17 | clear: both;
18 | height:1px;
19 | margin-top:-1px;
20 | overflow:hidden;
21 | &:before{
22 | display:none;
23 | }
24 | &:after{
25 | display:none;
26 | }
27 | }
28 |
29 | .border-box{
30 | @include box-sizing(border-box);
31 | }
32 |
33 | .content-wrap{
34 | @include box-sizing(content-wrap);
35 | }
36 |
37 | .block_area{
38 | margin: 0 auto;
39 | position: relative;
40 | font-size: 14px;
41 | }
42 |
43 | // inline-block对齐 或者文本对齐
44 | .text-left{
45 | text-align:left;
46 | }
47 |
48 | .text-right{
49 | text-align:right;
50 | }
51 |
52 | .text-center{
53 | text-align:center;
54 | }
55 |
56 | .text-bold{
57 | font-weight:bold;
58 | }
59 |
60 | .activeB{
61 | display: block;
62 | }
63 |
64 | .activeF{
65 | display: flex;
66 | }
67 |
68 | .activeN{
69 | display:none;
70 | }
71 |
72 |
73 | @for $i from 0 through 30 {
74 | .padding-top-#{$i}{
75 | padding-top: $i * 1px;
76 | }
77 | .padding-left-#{$i}{
78 | padding-left: $i * 1px;
79 | }
80 | .padding-right-#{$i}{
81 | padding-right: $i * 1px;
82 | }
83 | .padding-bottom-#{$i}{
84 | padding-bottom: $i * 1px;
85 | }
86 | .padding-#{$i}{
87 | padding: $i * 1px;
88 | }
89 |
90 | //--------------------
91 |
92 | .margin-top-#{$i}{
93 | margin-top: $i * 1px;
94 | }
95 | .margin-left-#{$i}{
96 | margin-left: $i * 1px;
97 | }
98 | .margin-right-#{$i}{
99 | margin-right: $i * 1px;
100 | }
101 | .margin-bottom-#{$i}{
102 | margin-bottom: $i * 1px;
103 | }
104 | .margin-#{$i}{
105 | padding: $i * 1px;
106 | }
107 |
108 |
109 | // -------------------
110 |
111 | .text-indent-#{$i}{
112 | text-indent: $i * 1px;
113 | }
114 |
115 | .border-r-#{$i}{
116 | @include border-radius($i * 1px)
117 | }
118 |
119 | .m-padding-top-#{$i}{
120 | padding-top: px75rem($i);
121 | }
122 | .m-padding-left-#{$i}{
123 | padding-left: px75rem($i);
124 | }
125 | .m-padding-right-#{$i}{
126 | padding-right: px75rem($i);
127 | }
128 | .m-padding-bottom-#{$i}{
129 | padding-bottom: px75rem($i);
130 | }
131 | .m-padding-#{$i}{
132 | padding: px75rem($i);
133 | }
134 |
135 | //--------------------
136 |
137 | .m-margin-top-#{$i}{
138 | margin-top: px75rem($i);
139 | }
140 | .m-margin-left-#{$i}{
141 | margin-left: px75rem($i);
142 | }
143 | .m-margin-right-#{$i}{
144 | margin-right: px75rem($i);
145 | }
146 | .m-margin-bottom-#{$i}{
147 | margin-bottom: px75rem($i);
148 | }
149 | .m-margin-#{$i}{
150 | padding: px75rem($i);
151 | }
152 |
153 |
154 | // -------------------
155 |
156 | .m-text-indent-#{$i}{
157 | text-indent: px75rem($i);
158 | }
159 |
160 | .m-border-r-#{$i}{
161 | @include border-radius(px75rem($i))
162 | }
163 | }
164 |
165 | @for $i from 10 through 50 {
166 | @if ($i % 2 == 0) {
167 | .m-size-#{$i}{
168 | font-size: px75rem($i);
169 | }
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/webpack.common.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
3 | // MiniCssExtractPlugin
4 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
5 |
6 | // HtmlWebpackPlugin
7 | const HtmlWebpackPlugin = require('html-webpack-plugin');
8 |
9 | const resolve = function (dir) {
10 | return path.resolve(__dirname, dir);
11 | }
12 |
13 | const devMode = process.env.NODE_ENV === "development"
14 |
15 | module.exports = {
16 | plugins: [
17 | new HtmlWebpackPlugin ({
18 | filename: 'index.html',
19 | template: 'index.html',
20 | inject: true,
21 | favicon: 'src/assets/favicon/favicon.ico'
22 | }),
23 |
24 | new MiniCssExtractPlugin ({
25 | filename: "css/[name]-[hash].css",
26 | chunkFilename: "css/[id].css"
27 | })
28 | ],
29 | module: {
30 | unknownContextCritical : false,
31 | rules: [
32 | {
33 | test: /\.(c)ss$/,
34 | use: [
35 | 'cache-loader',
36 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
37 | "css-loader",
38 | {
39 | loader:"postcss-loader",
40 | options: {
41 | plugins: (loader) => [
42 | require('autoprefixer')()
43 | ]
44 | }
45 | },
46 | "less-loader"
47 | ]
48 | },
49 | {
50 | test: /\.less$/,
51 | use: [
52 | 'cache-loader',
53 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
54 | "css-loader",
55 | {
56 | loader:"postcss-loader",
57 | options: {
58 | plugins: (loader) => [
59 | require('autoprefixer')()
60 | ]
61 | }
62 | },
63 | "less-loader"
64 | ],
65 | },
66 | {
67 | test: /\.styl$/,
68 | use: [
69 | 'cache-loader',
70 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
71 | "css-loader",
72 | {
73 | loader:"postcss-loader",
74 | options: {
75 | plugins: (loader) => [
76 | require('autoprefixer')()
77 | ]
78 | }
79 | },
80 | "stylus-loader"
81 | ]
82 | },
83 | {
84 | test: /\.(ttf|eot|svg|woff|woff2)$/,
85 | use: [
86 | 'cache-loader',
87 | {
88 | loader: 'url-loader'
89 | }
90 | ]
91 | },
92 | {
93 | test: /\.ts$/,
94 | use: [
95 | 'cache-loader',
96 | {loader: 'babel-loader',},
97 | {
98 | loader: 'ts-loader',
99 | options: {
100 | // 加快编译速度
101 | transpileOnly: true,
102 | // 指定特定的ts编译配置,为了区分脚本的ts配置
103 | configFile: path.resolve(__dirname, './tsconfig.json')
104 | }
105 | }
106 | ]
107 | },
108 | {
109 | test: /\.(png|jpg|gif)$/,
110 | use: [
111 | 'cache-loader',
112 | {
113 | loader: 'url-loader',
114 | options: {
115 | limit: 8192
116 | }
117 | }
118 | ]
119 | },
120 | ]
121 | },
122 | resolve: {
123 | alias: {
124 | '@': resolve('src'),
125 | assets: resolve('src/assets'),
126 | style: resolve('src/style')
127 | },
128 | extensions: ['.ts', '.tsx', '.js'],
129 | modules: ['src' ,'node_modules']
130 | },
131 | optimization: {
132 | splitChunks: {
133 | chunks: "all",
134 | minSize: 30000,
135 | minChunks: 3,
136 | maxAsyncRequests: 5,
137 | maxInitialRequests: 3,
138 | name: true,
139 | cacheGroups: {
140 | default: {
141 | minChunks: 2,
142 | priority: -20,
143 | reuseExistingChunk: true,
144 | },
145 | vendors: {
146 | test: /[\\/]node_modules[\\/]/,
147 | priority: -10
148 | }
149 | }
150 | },
151 | minimizer: [
152 | new UglifyJsPlugin({
153 | test: /\.js(\?.*)?$/i,
154 | parallel: true
155 | }),
156 | ]
157 | }
158 | };
--------------------------------------------------------------------------------
/src/style/common/less/_mixin.less:
--------------------------------------------------------------------------------
1 | .lineclamp (@height, @count) {
2 | height: @height;
3 | line-height: @height / @count;
4 | overflow:hidden;
5 | text-overflow:ellipsis;
6 | display:-webkit-box;
7 | -webkit-box-orient:vertical;
8 | -webkit-line-clamp: @count;
9 | word-wrap: break-word;
10 | }
11 |
12 | .textoneline(@height) when (@height = auto) {
13 | height: @height;
14 | line-height: initial;
15 | text-overflow: ellipsis;
16 | white-space: nowrap;
17 | overflow: hidden;
18 | }
19 |
20 | .textoneline(@height) when (@height = height) {
21 | height: @height;
22 | line-height: @height;
23 | text-overflow: ellipsis;
24 | white-space: nowrap;
25 | overflow: hidden;
26 | }
27 |
28 | // top left = > right bottom
29 | .colortext-lt (@color1, @color2) {
30 | position: relative;
31 | background: -webkit-linear-gradient(left top, @color1 , @color2); /* Safari 5.1 - 6.0 */
32 | background: -o-linear-gradient(bottom right, @color1, @color2); /* Opera 11.1 - 12.0 */
33 | background: -moz-linear-gradient(bottom right, @color1, @color2); /* Firefox 3.6 - 15 */
34 | background: linear-gradient(to bottom right, @color1 , @color2); /* 标准的语法 */
35 | -webkit-background-clip: text;
36 | -webkit-text-fill-color: transparent;
37 | }
38 |
39 | // left = > right
40 | .colortext-l (@color1, @color2) {
41 | position: relative;
42 | background: -webkit-linear-gradient(left, @color1 , @color2); /* Safari 5.1 - 6.0 */
43 | background: -o-linear-gradient(right, @color1, @color2); /* Opera 11.1 - 12.0 */
44 | background: -moz-linear-gradient(right, @color1, @color2); /* Firefox 3.6 - 15 */
45 | background: linear-gradient(to right, @color1 , @color2); /* 标准的语法 */
46 | -webkit-background-clip: text;
47 | -webkit-text-fill-color: transparent;
48 | }
49 |
50 | // 添加blur模糊效果
51 | // 如果不是绝对定位,父元素需要设置相对定位
52 | // @blur 为模糊的数值
53 | // @height 区域的高度
54 | // @position 为位置 默认50%
55 | .blur(@blur, @height, @position: 50%, @scale: 1.5) {
56 | position: absolute;
57 | top: 0;
58 | left: 0;
59 | right: 0;
60 | height: @height;
61 | background-repeat: no-repeat;
62 | background-size: cover;
63 | background-position: @position;
64 | -webkit-filter: blur(@blur);
65 | filter: blur(@blur);
66 | -webkit-transform: scale(@scale);
67 | transform: scale(@scale);
68 | overflow: hidden;
69 | &::before{
70 | content: '';
71 | position: absolute;
72 | left: 0;
73 | top: 0;
74 | right: 0;
75 | bottom: 0;
76 | z-index: 1;
77 | background: rgba(0,0,0,0.1);
78 | transition: all 0.3s;
79 | }
80 | &.draken{
81 | &::before{
82 | background: rgba(0,0,0,0.3);
83 | }
84 | }
85 | }
86 |
87 | .blur(@blur, @height, @position: 50%, @scale: 1.5) when (@height = auto) {
88 | bottom: 0;
89 | height: unset;
90 | }
91 |
92 | // 固定底部
93 | .fixfooterflex () {
94 | html{
95 | height: 100%;
96 | }
97 |
98 | body{
99 | display: flex;
100 | flex-direction: column;
101 | min-height: 100%;
102 | font-family: "Hiragino Sans GB","Century Gothic",system, Arial, Verdana, Tahoma,"微软雅黑";
103 | position: relative;
104 | width: 100%;
105 | overflow-x: hidden;
106 | }
107 |
108 | header{
109 | /* 我们希望 header 采用固定的高度,只占用必须的空间 */
110 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */
111 | flex: 0 0 auto;
112 | }
113 |
114 | .main_content{
115 | /* 将 flex-grow 设置为1,该元素会占用所有的可使用空间
116 | 而其他元素该属性值为0,因此不会得到多余的空间*/
117 | /* 1 flex-grow, 0 flex-shrink, auto flex-basis */
118 | flex: 1 1 auto;
119 | background-color: #fff;
120 | position:relative;
121 | }
122 |
123 | footer{
124 | /* 和 header 一样,footer 也采用固定高度*/
125 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */
126 | flex: 0 0 auto;
127 | }
128 | }
129 |
130 | // hr 线条和颜色
131 | .hr(@color, @name) {
132 | .hr-@{color} {
133 | width: 100%;
134 | height: 1px;
135 | background: @color;
136 | font-size: 0;
137 | margin: 0 auto;
138 | }
139 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) {
140 | transform: translate(0, 1 / 2 * 100'px');
141 | }
142 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) {
143 | transform: translate(0, 1 / 2 * 100'px');
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/src/style/common/scss/_mixin.scss:
--------------------------------------------------------------------------------
1 | //移动端通用样式 1rem 相当于100px算的 也就是 宽度 / 7.5的比例
2 | @function px75rem($px){
3 | $rem : 100px;
4 | @return ($px * 1px / $rem) + rem;
5 | }
6 |
7 | // 多少行限制超出省略
8 | @mixin lineclamp($height, $count, $isrem: false) {
9 | @if($isrem == false) {
10 | height: px75rem($height);
11 | line-height: px75rem($height / $count);
12 | } @else {
13 | height: $height;
14 | line-height: $height / $count;
15 | }
16 | overflow:hidden;
17 | text-overflow:ellipsis;
18 | display:-webkit-box;
19 | -webkit-box-orient:vertical;
20 | -webkit-line-clamp: $count;
21 | word-wrap: break-word;
22 | }
23 |
24 | @mixin textoneline ($height: auto) {
25 | height: $height;
26 | @if($height == auto) {
27 | line-height: initial;
28 | } else {
29 | line-height:$height;
30 | }
31 | @include ellipsis();
32 | }
33 |
34 |
35 | @mixin colortext-lt ($color1, $color2) {
36 | position: relative;
37 | @include background(linear-gradient(to bottom right, $color1, $color2));
38 | -webkit-background-clip: text;
39 | -webkit-text-fill-color: transparent;
40 | }
41 |
42 | @mixin colortext-l ($color1, $color2) {
43 | position: relative;
44 | @include background(linear-gradient(to right, $color1, $color2));
45 | -webkit-background-clip: text;
46 | -webkit-text-fill-color: transparent;
47 | }
48 |
49 | // 计算属性
50 | @mixin ccalc($pro, $all, $reduce) {
51 | #{$pro}: calc(#{$all} - #{$reduce});
52 | }
53 |
54 | // footer header content充满body
55 | @mixin fixfooter($headerH, $footerH) {
56 | body,html{
57 | min-height: unset!important;
58 | height: 100%!important;
59 | }
60 | .custom_header{
61 | height: $headerH;
62 | @include box-sizing(border-box);
63 | position: relative;
64 | }
65 | .custom_footer{
66 | height: $footerH;
67 | @include box-sizing(border-box);
68 | position: relative;
69 | }
70 | .custom_content{
71 | position: relative;
72 | background-color: #f0f0f0;
73 | min-height: calc(100% - #{$headerH} - #{$footerH});
74 | }
75 | }
76 |
77 | @mixin fixfooterflex () {
78 | html{
79 | height: 100%;
80 | }
81 |
82 | body{
83 | display: flex;
84 | flex-direction: column;
85 | min-height: 100%;
86 | // font-family: "Hiragino Sans GB","Century Gothic",system, Arial, Verdana, Tahoma,"微软雅黑";
87 | font-family: $font;
88 | position: relative;
89 | width: 100%;
90 | overflow-x: hidden;
91 | }
92 |
93 | header{
94 | /* 我们希望 header 采用固定的高度,只占用必须的空间 */
95 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */
96 | flex: 0 0 auto;
97 | }
98 |
99 | .main_content{
100 | /* 将 flex-grow 设置为1,该元素会占用所有的可使用空间
101 | 而其他元素该属性值为0,因此不会得到多余的空间*/
102 | /* 1 flex-grow, 0 flex-shrink, auto flex-basis */
103 | flex: 1 1 auto;
104 | background-color: $color_bg;
105 | position:relative;
106 | }
107 |
108 | footer{
109 | /* 和 header 一样,footer 也采用固定高度*/
110 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */
111 | flex: 0 0 auto;
112 | }
113 | }
114 |
115 | @mixin colorplaceholder($color) {
116 | ::-webkit-input-placeholder { /* WebKit browsers */
117 | color: $color;
118 | }
119 | :-moz-placeholder { /* Mozilla Firefox 4 to 18 */
120 | color: $color;
121 | opacity: 1;
122 | }
123 | ::-moz-placeholder { /* Mozilla Firefox 19+ */
124 | color: $color;
125 | opacity: 1;
126 | }
127 | :-ms-input-placeholder { /* Internet Explorer 10+ */
128 | color: $color;
129 | }
130 | }
131 |
132 | // 字体文字颜色的mixin
133 | @mixin colortext($color, $name) {
134 | .color-#{$name}{
135 | color: $color;
136 | }
137 | }
138 |
139 | // hr 线条和颜色
140 | @mixin hr($color, $name) {
141 | .hr-#{$name}{
142 | width: 100%;
143 | height: 1px;
144 | background: $color;
145 | font-size: 0;
146 | margin: 0 auto;
147 | }
148 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) {
149 | @include translate(0, 1 / 2 * 100'px');
150 | }
151 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) {
152 | @include translate(0, 1 / 2 * 100'px');
153 | }
154 | }
155 |
156 | // fixed布局铺面全屏
157 | @mixin fixedfull() {
158 | position: fixed;
159 | right: 0;
160 | top: 0;
161 | left: 0;
162 | bottom: 0;
163 | }
164 |
165 | // 不同背景图片使用不同的尺寸
166 | @mixin bgimage($url, $type: png, $hasmedia: false){
167 | @if($hasmedia == true){
168 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) {
169 | background-image: url($url + "@2x." + $type)
170 | }
171 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) {
172 | background-image: url($url + "@3x." + $type)
173 | }
174 | }
175 | background-image: url($url + "." + $type)
176 | }
177 |
178 |
--------------------------------------------------------------------------------
/src/exp.ts:
--------------------------------------------------------------------------------
1 | import { LogUtils } from '@dw/d-utils'
2 | const Exp1 = /\bhi\b/
3 | // \b 匹配单词的开始或结束
4 | LogUtils.logInfo(Exp1.test('hi'))
5 | LogUtils.logInfo(Exp1.test('hi2'))
6 | LogUtils.logError('', '--------------------------------------')
7 | const Exp2 = /\bhi\b.\bLucy\b/
8 | LogUtils.logInfo(Exp2.test('hi Lucy'))
9 | LogUtils.logInfo(Exp2.test('hi aaa Lucy'))
10 |
11 | // 匹配字符长度
12 | // ^匹配你 要用来查找的字符串的开头,$匹配结尾。
13 | LogUtils.logInfo(/^\d{5,12}$/.test('11111'))
14 | LogUtils.logError('', '--------------------------------------')
15 | // w 匹配一个单字字符(字母、数字或者下划线)等价于[A-Za-z0-9_]
16 | LogUtils.logInfo(/\w/.test('aaaaa')) // true
17 | LogUtils.logInfo(/\w/.test('111')) // true
18 | LogUtils.logInfo(/\w/.test('z')) // true
19 | LogUtils.logInfo(/\w/.test('_')) // true
20 | // 匹配一个非单字字符。等价于[^A-Za-z0-9_]
21 | LogUtils.logInfo(/\W/.test('_')) // false
22 | LogUtils.logError('', '--------------------------------------')
23 | // 匹配字符串的开始用在[]括号里面表示排除,/^A/ 并不会匹配 "an A" 中的 'A',但是会匹配 "An E" 中的 'A'。
24 | LogUtils.logInfo(/\W/.test('a&&')) // true
25 | LogUtils.logInfo(/^\W/.test('a&&')) // false
26 | LogUtils.logInfo(/^\W/.test('&a&&')) // true
27 | LogUtils.logError('', '--------------------------------------')
28 | LogUtils.logInfo(/[^\w]/.test('a')) // true 相当于 /\W/
29 | LogUtils.logInfo(/[^\W]/.test('a')) // true
30 | // $ 匹配字符串的结束。例如,/t$/ 并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。 QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$
31 | LogUtils.logInfo(/[^\W]$/.test('a_&')) // false
32 | LogUtils.logInfo(/[^\W]$/.test('a&_')) // true
33 |
34 | LogUtils.logError('', '--------------------------------------')
35 | // s 代表任意空白符(换行符,制表符,空格)
36 | LogUtils.logInfo(/\s/.test(' ')) // true
37 |
38 |
39 | // d 匹配一个数字,等价于[0-9]
40 | LogUtils.logInfo(/\d/.test(' ')) // false
41 | LogUtils.logInfo(/\d/.test('1111')) // true
42 | // D 匹配一个数字,等价于[^0-9]
43 | LogUtils.logInfo(/\d/.test('1111')) // false
44 | LogUtils.logError('', '--------------------------------------')
45 |
46 | // () 代表一个组 如果想要重复多个字符该怎么办?你可以用小括号来指定子表达式(也叫做分组)
47 | LogUtils.logInfo(/(\d{1,3}\.){3}\d{1,3}/.test('222.222.222.1')) // true
48 | LogUtils.logInfo([/\w.+/.test('test.i.ng'), /[a-z.]+/.test('test.i.ng')]) // true
49 | LogUtils.logInfo(/\w{3,5}/.test('___')) // true
50 | LogUtils.logInfo(/\d{3,5}/.test('___')) // true
51 | LogUtils.logError('', '--------------------------------------')
52 | // i 忽略大小写
53 | LogUtils.logInfo(/a/.test('aaaaaa')) // true
54 | LogUtils.logInfo(/a/.test('AAAAAA')) // false
55 | LogUtils.logInfo(/a/i.test('AAAAAA')) // true
56 | LogUtils.logError('', '--------------------------------------')
57 | // g 执行全局匹配
58 | LogUtils.logInfo(/a/.test('vvvvva')) // true
59 | const Exp3 = /a/g
60 | const str = 'aaaaaaaa'
61 | LogUtils.logInfo(Exp3.test(str)) // true
62 | LogUtils.logWarning(Exp3.lastIndex)
63 | LogUtils.logInfo(Exp3.test(str)) // true
64 | LogUtils.logWarning(Exp3.lastIndex)
65 | LogUtils.logInfo(Exp3.test(str)) // true
66 | LogUtils.logWarning(Exp3.lastIndex)
67 | LogUtils.logInfo(Exp3.test(str)) // true
68 | LogUtils.logWarning(Exp3.lastIndex)
69 | LogUtils.logError('', '--------------------------------------')
70 | //
71 | const str1 = 'daiwei'
72 | LogUtils.logInfo(/d(?=a)/.test(str1))
73 | LogUtils.logInfo(/d(?=i|a)/.test(str1))
74 |
75 | const num = '021-121121'
76 | LogUtils.logInfo(/\(?0\d{2}[)-]?\d{6}/.test(num))
77 |
78 | // 6-12 数字 字母 下划线
79 | const pwd = 'Daiwei__12'
80 | LogUtils.logInfo(/^\w{6,12}$/.test(pwd))
81 | LogUtils.logError('', '--------------------------------------')
82 | const str2 = 'Hi RegExp I love you so much Hi Hi hi'
83 | const Exp4 = /\bhi\b/gi
84 | const Exp5 = /\bhi\b.*\bmuch\b/gi
85 | LogUtils.logInfo(Exp4.test(str2))
86 | LogUtils.logInfo(Exp4.lastIndex)
87 | LogUtils.logInfo(Exp4.test(str2))
88 | LogUtils.logInfo(Exp4.lastIndex)
89 | LogUtils.logInfo(Exp4.test(str2))
90 | LogUtils.logInfo(Exp4.lastIndex)
91 | LogUtils.logInfo(Exp4.test(str2))
92 | LogUtils.logInfo(Exp4.lastIndex)
93 | LogUtils.logInfo(str2.match(Exp4))
94 | LogUtils.logInfo(Exp5.test(str2))
95 | LogUtils.logInfo(str2.match(Exp5))
96 | LogUtils.logError('', '--------------------------------------')
97 |
98 | // 匹配手机号 0123-88752314
99 | const Exp6 = /^0\d{3}-\d{8}$/g
100 | LogUtils.logInfo(Exp6.test('0123-45678910'))
101 | LogUtils.logInfo(Exp6.test('0123-456789101'))
102 | LogUtils.logInfo(Exp6.test('10123-456789101'))
103 | LogUtils.logInfo('0123-45678910'.match(Exp6))
104 | LogUtils.logInfo('0123-456789101'.match(Exp6))
105 | LogUtils.logInfo('10123-456789101'.match(Exp6))
106 | LogUtils.logError('', '--------------------------------------')
107 |
108 | // 清除字符串首尾表达式
109 | const str3 = ' this is space '
110 | const Exp7 = /(^\s*) | (\s*$)/g
111 | // 去除所有空格
112 | const Exp8 = /(\s)/g
113 | LogUtils.logInfo(str3)
114 | LogUtils.logInfo(str3.replace(Exp7, ''))
115 | LogUtils.logInfo(str3.replace(Exp8, ''))
116 | LogUtils.logError('', '--------------------------------------')
117 |
118 | // 匹配一个邮箱。 185098535@qq.com
119 | const Exp9 = /\S*@\S*\.\S*/
120 | const str4 = '18509535@qq.com'
121 | LogUtils.logInfo(Exp9.test(str4))
122 | LogUtils.logError('', '--------------------------------------')
123 |
124 | // 练习只能是汉字
125 | const Exp10 = /^[\u4e00-\u9fa5]*$/g
126 | const str5 = '戴伟'
127 | LogUtils.logInfo(Exp10.test(str5))
128 | LogUtils.logInfo('JavaScript'.search(/a(.)a/))
129 |
130 |
--------------------------------------------------------------------------------