lovelmh13 / myBlog

个人博客 记录菜狗的学习之路
6 stars 0 forks source link

小程序使用webpack编译scss成wxss #36

Open lovelmh13 opened 4 years ago

lovelmh13 commented 4 years ago

首先说明,webpack.config.js 的代码来自于 【webpack】【小程序】小程序使用sass,使用webpack单独处理sass到wxss

把每个页面文件夹里面的scss/css文件编译成wxss供小程序使用其他文件不做处理: 使用工具先获取到所有需要处理的scss/css文件以及路径; 通过scss-loader编译成css; 通过插件将编译后的css文件根据获取的路径输出到相应的文件夹并改后缀为.wxss;

先来看一下整体代码和效果:

image

image

为什么用 webpack 来编译 scss

首先说说一下,为什么用webpack

网上搜了一下,社区里面有官方的人说没必要用scss, 看是原生的wxss写起来的确有那么一丝的不爽。

然后看到之前有人用gulp来编译scss,但是在这个webpack一统天下的时代,未来可能还会需要用到其他的编译的功能,gulp没有webpack来的方便。

思路

通过设置 多入口起点, 来使得每个有scss的目录下,都生成一个对应的wxss

修改一下目录结构

在当前目录下npm init一下,创建一个src目录,把除了project.config.json之外的小程序文件都放进src中。

找到scss文件所在的目录

// CSS入口配置
const CSS_PATH = {
    pattern: [ './src/**/*.scss', './src/**/*.css' ],
    src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
    let fileList = glob.sync(config.pattern);
    return fileList.reduce((previous, current) => {
        let filePath = path.parse(path.relative(config.src, current));
        let withoutSuffix = path.join(filePath.dir, filePath.name);
        previous[withoutSuffix] = path.resolve(__dirname, current);
        return previous;
    }, {});
};

这里如果打印一下,就会看见我们已经拿到了每个scss文件所在的目录: image

loader 配置

module: {
    rules: [
        {
            test: /\.(scss|sass|css)$/,
            use: [
                // 需要用到的 loader
                MiniCssExtractPlugin.loader,
                'css-loader',
                'sass-loader'
            ]
        }
    ]
},

全部的配置

webpack.config.js

// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
    pattern: [ './src/**/*.scss', './src/**/*.css' ],
    src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
    let fileList = glob.sync(config.pattern);
    return fileList.reduce((previous, current) => {
        let filePath = path.parse(path.relative(config.src, current));
        let withoutSuffix = path.join(filePath.dir, filePath.name);
        previous[withoutSuffix] = path.resolve(__dirname, current);
        return previous;
    }, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
    entry: getCSSEntries(CSS_PATH),
    output: {
        path: __dirname
    },
    module: {
        rules: [
            {
                test: /\.(scss|sass|css)$/,
                use: [
                    // 需要用到的 loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new FixStyleOnlyEntriesPlugin(),
        new MiniCssExtractPlugin({
            filename: '/src/[name].wxss'
        })
    ],
    resolve: {
        extensions: [ '.scss' ]
    }
};

module.exports = config;

package.json

可以使用 cross-env , 或者直接写webpack --webpack.config.js

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack --webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

修改 project.config.json 编译入口

{
    "description": "项目配置文件",
    "miniprogramRoot": "src/",
        ...
}

运行npm run dev

为了方便,可以在小程序开发工具 -> 详情 -> 本地设置 -> 启用自定义处理命令 写上 npm run dev

lovelmh13 commented 4 years ago

首先说明,webpack.config.js 的代码来自于 【webpack】【小程序】小程序使用sass,使用webpack单独处理sass到wxss

把每个页面文件夹里面的scss/css文件编译成wxss供小程序使用其他文件不做处理: 使用工具先获取到所有需要处理的scss/css文件以及路径; 通过scss-loader编译成css; 通过插件将编译后的css文件根据获取的路径输出到相应的文件夹并改后缀为.wxss;

先来看一下整体代码和效果:

image

image

为什么用 webpack 来编译 scss

首先说说一下,为什么用webpack

网上搜了一下,社区里面有官方的人说没必要用scss, 看是原生的wxss写起来的确有那么一丝的不爽。

然后看到之前有人用gulp来编译scss,但是在这个webpack一统天下的时代,未来可能还会需要用到其他的编译的功能,gulp没有webpack来的方便。

思路

通过设置 多入口起点, 来使得每个有scss的目录下,都生成一个对应的wxss

修改一下目录结构

在当前目录下npm init一下,创建一个src目录,把除了project.config.json之外的小程序文件都放进src中。

找到scss文件所在的目录

// CSS入口配置
const CSS_PATH = {
  pattern: [ './src/**/*.scss', './src/**/*.css' ],
  src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
  let fileList = glob.sync(config.pattern);
  return fileList.reduce((previous, current) => {
      let filePath = path.parse(path.relative(config.src, current));
      let withoutSuffix = path.join(filePath.dir, filePath.name);
      previous[withoutSuffix] = path.resolve(__dirname, current);
      return previous;
  }, {});
};

这里如果打印一下,就会看见我们已经拿到了每个scss文件所在的目录: image

loader 配置

module: {
  rules: [
      {
          test: /\.(scss|sass|css)$/,
          use: [
              // 需要用到的 loader
              MiniCssExtractPlugin.loader,
              'css-loader',
              'sass-loader'
          ]
      }
  ]
},

全部的配置

webpack.config.js

// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
  pattern: [ './src/**/*.scss', './src/**/*.css' ],
  src: path.join(__dirname, 'src')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
  let fileList = glob.sync(config.pattern);
  return fileList.reduce((previous, current) => {
      let filePath = path.parse(path.relative(config.src, current));
      let withoutSuffix = path.join(filePath.dir, filePath.name);
      previous[withoutSuffix] = path.resolve(__dirname, current);
      return previous;
  }, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
  entry: getCSSEntries(CSS_PATH),
  output: {
      path: __dirname
  },
  module: {
      rules: [
          {
              test: /\.(scss|sass|css)$/,
              use: [
                  // 需要用到的 loader
                  MiniCssExtractPlugin.loader,
                  'css-loader',
                  'sass-loader'
              ]
          }
      ]
  },
  plugins: [
      new FixStyleOnlyEntriesPlugin(),
      new MiniCssExtractPlugin({
          filename: '/src/[name].wxss'
      })
  ],
  resolve: {
      extensions: [ '.scss' ]
  }
};

module.exports = config;

package.json

可以使用 cross-env , 或者直接写webpack --webpack.config.js

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack --webpack.config.js",
    "build": "cross-env NODE_ENV=production webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

修改 project.config.json 编译入口

{
  "description": "项目配置文件",
  "miniprogramRoot": "src/",
        ...
}

运行npm run dev

为了方便,可以在小程序开发工具 -> 详情 -> 本地设置 -> 启用自定义处理命令 写上 npm run dev

这个方法对于要使用npm包不是很友好,所以,我又改了一下,让它方便npm的使用。

修改project.config.json 编译入口

删掉

{
    "description": "项目配置文件",
        ...
}

前两步,说白了就是还原我们小程序一开始的配置和结构

调整目录结构

首先,我们调整一下之前的目录结构,删掉src,把src里面的东西拿出来,就跟微信小程序一开始给我们生成的目录结构一样。

编写config文件

// webpack.config.js
// 单独打包样式文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//删除多余js
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries');
const path = require('path');
const glob = require('globby');
// CSS入口配置
const CSS_PATH = {
    pattern: [ './pages/**/*.scss', './pages/**/*.css',  './style/**/*.scss', './style/**/*.css', './utils/**/*.scss', './utils/**/*.css' ],
    src: path.join(__dirname, './')
};

// 遍历所有需要打包的SCSS/CSS文件路径
let getCSSEntries = (config) => {
    let fileList = glob.sync(config.pattern);
    return fileList.reduce((previous, current) => {
        let filePath = path.parse(path.relative(config.src, current));
        let withoutSuffix = path.join(filePath.dir, filePath.name);
        previous[withoutSuffix] = path.resolve(__dirname, current);
        return previous;
    }, {});
};
console.log('getCSSEntries', getCSSEntries(CSS_PATH))
console.log('__dirname', __dirname)
let config = {
    entry: getCSSEntries(CSS_PATH),
    output: {
        path: __dirname
    },
    module: {
        rules: [
            {
                test: /\.(scss|sass|css)$/,
                exclude: /node_modules/, // 排除掉node_modules,不过不加现在貌似也不会编译node_modules
                use: [
                    // 需要用到的 loader
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new FixStyleOnlyEntriesPlugin(),
        new MiniCssExtractPlugin({
            filename: '/[name].wxss'
        })
    ],
    resolve: {
        extensions: [ '.scss' ]
    }
};

module.exports = config;
lovelmh13 commented 3 years ago

新思路: 像 taro 一样,在小程序之外去 build 代码,小程序去引用编译后的 dist 目录。就不用去在小程序开发工具里去设置预处理等命令了