浏览代码

webpack init

Johnhong9527 5 年之前
父节点
当前提交
b7291158cb
共有 13 个文件被更改,包括 291 次插入3 次删除
  1. 20 0
      .babelrc
  2. 4 0
      .browserslistrc
  3. 1 1
      .gitignore
  4. 51 0
      config/webpack.common.config.js
  5. 42 0
      config/webpack.dev.config.js
  6. 89 0
      config/webpack.prod.config.js
  7. 27 2
      package.json
  8. 5 0
      postcss.config.js
  9. 12 0
      public/index.html
  10. 17 0
      src/app.jsx
  11. 18 0
      src/app.less
  12. 二进制
      src/images/background.jpg
  13. 5 0
      src/index.js

+ 20 - 0
.babelrc

@@ -0,0 +1,20 @@
+{
+  "presets": [
+    [
+      "@babel/preset-env",
+      {
+        "targets": {
+          // 大于相关浏览器版本无需用到 preset-env
+          "edge": 17,
+          "firefox": 60,
+          "chrome": 49,
+          "safari": 11
+        },
+        "corejs": "2", // <---
+        // 根据代码逻辑中用到的 ES6+语法进行方法的导入,而不是全部导入
+        "useBuiltIns": "usage"
+      }
+    ],
+    "@babel/preset-react"
+  ]
+}

+ 4 - 0
.browserslistrc

@@ -0,0 +1,4 @@
+> 1%
+chrome 49
+ie 9
+

+ 1 - 1
.gitignore

@@ -2,7 +2,7 @@ package-lock.json
 *.lock
 .DS_Store
 node_modules
-# /dist
+dist
 
 # local env files
 .env.local

+ 51 - 0
config/webpack.common.config.js

@@ -0,0 +1,51 @@
+const path = require('path');
+
+module.exports = {
+  entry: {
+    index: './src/index.js',
+    framework: ['react', 'react-dom'],
+  },
+  output: {
+    filename: 'js/bundle.js',
+    path: path.resolve(__dirname, '../dist'),
+  },
+
+  module: {
+    rules: [
+      {
+        test: /\.(js|jsx)$/,
+        use: 'babel-loader',
+        exclude: /node_modules/,
+      },
+      {
+        test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
+        use: [
+          {
+            loader: 'url-loader',
+            options: {
+              name: '[name].[ext]',
+              outputPath: 'images/',
+              limit: 4096,
+              fallback: {
+                loader: 'file-loader',
+                options: {
+                  name: 'img/[name].[hash:8].[ext]',
+                },
+              },
+            },
+          },
+        ],
+      },
+      {
+        test: /\.(eot|ttf|svg|woff|woff2)$/,
+        use: {
+          loader: 'file-loader',
+          options: {
+            name: '[name]_[hash].[ext]',
+            outputPath: 'font/',
+          },
+        },
+      },
+    ],
+  },
+};

+ 42 - 0
config/webpack.dev.config.js

@@ -0,0 +1,42 @@
+const path = require('path');
+const merge = require('webpack-merge');
+const common = require('./webpack.common.config.js');
+
+const webpack = require('webpack');
+const HtmlWebpackPlugin = require('html-webpack-plugin', null, 2);
+
+const webpack_config = merge(common, {
+  mode: 'development',
+  output: {
+    filename: 'js/[name].[hash:8].bundle.js',
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        use: ['style-loader', 'css-loader', 'postcss-loader'],
+      },
+      {
+        test: /\.less$/,
+        use: ['style-loader', 'css-loader', 'postcss-loader', 'less-loader'],
+      },
+    ],
+  },
+  devServer: {
+    contentBase: path.resolve(__dirname, '../dist'),
+    open: true,
+    port: 9000,
+    compress: true,
+    hot: true,
+  },
+  plugins: [
+    new HtmlWebpackPlugin({
+      template: 'public/index.html',
+      inject: 'body',
+      hash: false,
+    }),
+    new webpack.HotModuleReplacementPlugin(),
+  ],
+});
+
+module.exports = webpack_config;

+ 89 - 0
config/webpack.prod.config.js

@@ -0,0 +1,89 @@
+const merge = require('webpack-merge');
+const common = require('./webpack.common.config.js');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
+
+module.exports = merge(common, {
+  mode: 'production',
+  output: {
+    filename: 'js/[name].[chunkhash:8].bundle.js',
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
+      },
+      {
+        test: /\.less$/,
+        use: [
+          MiniCssExtractPlugin.loader,
+          'css-loader',
+          'less-loader',
+          'postcss-loader',
+        ],
+      },
+      // {
+      //   test: /\.(scss|sass)$/,
+      //   use: [
+      //     MiniCssExtractPlugin.loader,
+      //     'css-loader',
+      //     'postcss-loader',
+      //     'sass-loader'
+      //   ]
+      // },
+    ],
+  },
+  plugins: [
+    new HtmlWebpackPlugin({
+      filename: 'index.html',
+      template: 'public/index.html',
+      inject: 'body',
+      minify: {
+        removeComments: true,
+        collapseWhitespace: true,
+      },
+    }),
+    new CleanWebpackPlugin(),
+    new MiniCssExtractPlugin({
+      filename: 'css/[name].[hash].css',
+      chunkFilename: 'css/[id].[hash].css',
+    }),
+  ],
+  optimization: {
+    minimizer: [
+      new UglifyJsPlugin(),
+      new OptimizeCssAssetsPlugin({
+        assetNameRegExp: /\.css$/g,
+        cssProcessor: require('cssnano'),
+        cssProcessorPluginOptions: {
+          preset: ['default', { discardComments: { removeAll: true } }],
+        },
+        canPrint: true,
+      }),
+    ],
+    splitChunks: {
+      chunks: 'all',
+      minSize: 30000,
+      maxSize: 0,
+      minChunks: 1,
+      cacheGroups: {
+        framework: {
+          test: 'framework',
+          name: 'framework',
+          enforce: true,
+        },
+        vendors: {
+          priority: -10,
+          test: /node_modules/,
+          name: 'vendor',
+          enforce: true,
+        },
+      },
+    },
+  },
+});

+ 27 - 2
package.json

@@ -4,12 +4,37 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "serve": "webpack-dev-server --inline --config ./config/webpack.dev.config.js",
+    "build": "webpack --config ./config/webpack.prod.config.js"
   },
   "author": "",
   "license": "ISC",
+  "dependencies": {
+    "react": "^16.13.1",
+    "react-dom": "^16.13.1"
+  },
   "devDependencies": {
+    "@babel/core": "^7.9.6",
+    "@babel/preset-env": "^7.9.6",
+    "@babel/preset-react": "^7.9.4",
+    "autoprefixer": "^9.7.6",
+    "babel-loader": "^8.1.0",
+    "clean-webpack-plugin": "^3.0.0",
+    "css-loader": "^3.5.3",
+    "file-loader": "^6.0.0",
+    "html-webpack-plugin": "^4.3.0",
+    "less": "^3.11.1",
+    "less-loader": "^6.1.0",
+    "mini-css-extract-plugin": "^0.9.0",
+    "optimize-css-assets-webpack-plugin": "^5.0.3",
+    "postcss-loader": "^3.0.0",
+    "style-loader": "^1.2.1",
+    "uglifyjs-webpack-plugin": "^2.2.0",
+    "url-loader": "^4.1.0",
     "webpack": "^4.43.0",
-    "webpack-cli": "^3.3.11"
+    "webpack-cli": "^3.3.11",
+    "webpack-dev-server": "^3.10.3",
+    "webpack-merge": "^4.2.2"
   }
 }

+ 5 - 0
postcss.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  plugins: {
+    autoprefixer: {},
+  },
+};

+ 12 - 0
public/index.html

@@ -0,0 +1,12 @@
+<!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>从零配置webpack4+react脚手架</title>
+  </head>
+  <body>
+    <div id="root"></div>
+  </body>
+</html>

+ 17 - 0
src/app.jsx

@@ -0,0 +1,17 @@
+import React from 'react';
+import './app.less';
+import background from './images/background.jpg';
+
+function App() {
+  console.log(background);
+
+  return (
+    <div className="App">
+      <h1>I am changed</h1>
+      <div>{background}</div>
+      <img className="background" src={background} alt="" />
+    </div>
+  );
+}
+
+export default App;

+ 18 - 0
src/app.less

@@ -0,0 +1,18 @@
+.App {
+  height: 300px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background-color: lightcoral;
+  h1 {
+    font-size: 16px;
+    color: #fff;
+  }
+  .background {
+    position: absolute;
+    width: 100%;
+    left: 0;
+    top: -124px;
+    z-index: -1;
+  }
+}

二进制
src/images/background.jpg


+ 5 - 0
src/index.js

@@ -0,0 +1,5 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './app.jsx';
+
+ReactDOM.render(<App />, document.getElementById('root'));