Razzle: Razzle SCSS مع وحدات CSS

تم إنشاؤها على ٢٦ مايو ٢٠١٨  ·  4تعليقات  ·  مصدر: jaredpalmer/razzle

أحاول تنفيذ وحدات CSS باستخدام SCSS.

تمكنت من نقله إلى وحدات للعمل مع SCSS. ومع ذلك ، لا يمكنني القيام بعمليات الاستيراد العادية لـ SCSS ، لقد حاولت دفع قواعد متعددة ، واستبعاد module.scss لكنها لا تعمل. سيكون من الجيد أن يساعدني أي شخص هنا في هذا.

هذا هو تكوين عملي الحالي لـ SCSS مع الوحدات النمطية فقط ، لكن الاستيراد العادي.

شكرا.

'use strict';

const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');

const scssPlugin = new ExtractTextPlugin(
  'static/css/[name].[hash:8].css'
);

module.exports = {
  modify: (baseConfig, { target, dev }, webpack) => {
    const appConfig = Object.assign({}, baseConfig);

    appConfig.resolve.modules.push('src', 'node_modules');

    // Setup SCSS
    if (target === 'web') {
      appConfig.module.rules.push(
        dev
        ? {
          test: /\.scss$/,
          use: [
            'style-loader',
            {
              loader: 'css-loader',
              options: {
                modules: true,
                sourceMap: true,
                localIdentName: '[local]__[hash:base64:5]'
              },
            },
            {
              loader: 'postcss-loader',
              options: {
                ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                plugins: () => [
                  autoprefixer({
                      browsers: [
                        '>1%',
                        'last 4 versions',
                        'Firefox ESR',
                        'not ie < 9', // React doesn't support IE8 anyway
                        ],
                  }),
                    ],
              },
            },
            'sass-loader',
              ],
        }
        : {
          test: /\.scss$/,
          use: scssPlugin.extract({
              fallback: 'style-loader',
              use: [
                {
                  loader: 'css-loader',
                  options: {
                    modules: true,
                    minimize: true,
                    importLoaders: 1,
                    localIdentName: '[hash:base64:5]'
                  },
                },
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                  plugins: () => [
                    autoprefixer({
                        browsers: [
                          '>1%',
                          'last 4 versions',
                          'Firefox ESR',
                          'not ie < 9', // React doesn't support IE8 anyway
                          ],
                    }),
                      ],
                },
              },
                'sass-loader',
                ],
          }),
        }
      );


    } else {
      // On the server, we can just simply use css-loader to
      // deal with scss imports
      appConfig.module.rules.push(
        dev ? {
          test: /\.scss$/,
          use: scssPlugin.extract({
              fallback: 'style-loader',
              use: [
                {
                  loader: 'css-loader',
                  options: {
                    modules: true,
                    minimize: true,
                    importLoaders: 1,
                    localIdentName: '[local]__[hash:base64:5]'
                  },
                },
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                  plugins: () => [
                    autoprefixer({
                        browsers: [
                          '>1%',
                          'last 4 versions',
                          'Firefox ESR',
                          'not ie < 9', // React doesn't support IE8 anyway
                    ],
                    }),
                ],
                },
              },
                'sass-loader',
          ],
          })
        }
        : {
          test: /\.scss$/,
          use: scssPlugin.extract({
              fallback: 'style-loader',
              use: [
                {
                  loader: 'css-loader',
                  options: {
                    modules: true,
                    minimize: true,
                    importLoaders: 1,
                    localIdentName: '[hash:base64:5]'
                  },
                },
              {
                loader: 'postcss-loader',
                options: {
                  ident: 'postcss', // https://webpack.js.org/guides/migrating/#complex-options
                  plugins: () => [
                    autoprefixer({
                        browsers: [
                          '>1%',
                          'last 4 versions',
                          'Firefox ESR',
                          'not ie < 9', // React doesn't support IE8 anyway
                        ],
                    }),
                    ],
                },
              },
                'sass-loader',
              ],
          }
          ),
      });
    }


  appConfig.plugins.push(scssPlugin);

  return appConfig;
  },
};

التعليق الأكثر فائدة

تأخرت قليلاً في هذا الأمر ، ولكن إليك ما نجح معي:

const path = require("path");

module.exports = {
    modify(config, { target, dev }, webpack) {
        for (const rule of config.module.rules) {
            if (rule.test && rule.test.toString() === "/\\.module\\.css$/") {
                const scss = { ...rule };

                scss.test = /\.scss$/;
                scss.include = path.join(__dirname, "src");
                scss.use.push({ loader: "sass-loader" });

                config.module.rules.push(scss);

                break;
            }
        }

        return config;
    }
};

ال 4 كومينتر

نلقي نظرة على
https://github.com/natanelia/razzle-afterjs-redux-rnw-example
في هذا المثال ، يستخدم الإصدار السابق إصدارًا سابقًا من razzle (يستخدم webpack3) ، ولكن تعمل الإعدادات ذات الصلة بـ sass. سيتعين عليك إزالة ExtractTextPlugin لأنه لا يدعم webpack4 (الذي يعتمد عليه razzle الجديد).

أيضًا إذا كنت ترغب في الحصول على نهب في تحديثاتي لهذا المثال (لـ webpack 4) ، فاحصل على غنيمة أدناه:

const path = require('path');
const resolve=path.resolve;

const autoprefixer = require('autoprefixer');
const fs=require('fs'); 

//var treeify = require('treeify');

const { BundleAnalyzerPlugin } = require( "webpack-bundle-analyzer" );
const paths= require ('razzle/config/paths');

//does not yet work with webpack4
//const InlineChunkManifestHtmlWebpackPlugin = require('inline-chunk-manifest-html-webpack-plugin');

//keep it here,but could not get to work for sass...
const MiniCssExtractPlugin = require("mini-css-extract-plugin");


/* finds an index of babel rules in array of webpack rules */
/*
   {
   'ruleIdx':'',
   'useIdx':''
   }
 */

function getIdx_RulesByLoader (inRulesArr,
                               IS_DEV,
                               IS_WEB,
                               loaderStr,
                               extentionRegExTest) {

  let jsRulesBabelLoaderIdx = -1;
  let useIdx=-1;
  jsRulesBabelLoaderIdx=inRulesArr.findIndex(
    (rule) =>{
      if (rule.test // rule.test is a reg expr 
          && rule.test.exec
          && rule.test.exec(extentionRegExTest)
          && rule.use)
        {
          useIdx=rule.use.findIndex(
            (useItem)=> {
              if (useItem.options
                  && useItem.loader.includes(loaderStr) ){
                return true;
              }
            }
          );
          /*return true if useIdx is a valid index */
          return (useIdx>-1);
        }
    }
  );

  const res={
    'ruleIdx':jsRulesBabelLoaderIdx,
    'useIdx':useIdx
  };

  return res;
}





module.exports = {
  modify(baseConfig, secondArg, webpack) {

    const {target, dev}=secondArg;
    /* make a copy of config */
    const config = Object.assign({}, baseConfig);


    const IS_NODE = target === 'node';
    const IS_WEB = target === 'web';
    const IS_PROD = !dev;
    const IS_DEV = dev; 


    const MYpostCssLoader = {
      loader: 'postcss-loader',
      options: {
        ident: 'postcss',
        sourceMap: IS_DEV,
        plugins: () => [
          autoprefixer({
            browsers: ['>1%',
                       'last 4 versions',
                       'Firefox ESR',
                       'not ie < 9'],
          }),
        ],
      },
    };



    const MYscssLoader = {
      loader: 'sass-loader',
      options: {
        includePaths: [path.resolve(__dirname, './node_modules')],
        sourceMap: IS_DEV
      }};


    const MYcssLoader = IS_NODE ?
                        {loader:"css-loader"}
                       :{
                         loader: "css-loader",
                         options: {
                           minimize: !IS_DEV,
                           sourceMap: IS_DEV,
                           importLoaders: 1,
                           localIdentName:
IS_DEV?'[path]__[name]___[local]':undefined,
                         }
                       };


    /* 
       MiniCssExtractPlugin
       plugin should be used only on 
       production builds without style-loader 
       in the loaders chain, especially if you 
       want to have HMR in development.
     */

    const newSaasRule= {
      test: /\.(sass|scss)$/,
      exclude:[path.resolve(__dirname, './node_modules')],
      use: IS_NODE
         ? [MYcssLoader, MYscssLoader]
         : IS_DEV
         ? [
           'style-loader',
           MYcssLoader,
           MYpostCssLoader,
           MYscssLoader
         ]
          :[
            //'style-loader',
            MYcssLoader,            
            //cannot get this to work      MiniCssExtractPlugin.loader,
            MYpostCssLoader,
            MYscssLoader
          ]
    };//end of newSaasRule


    config.module.rules.push(newSaasRule);


    /* make babel to transply My symlinked directors
       This is relevant to My seetup (others may not have symlinks..)
       and from some directories containing react native modules
       @start<strong i="10">@step</strong>:1
     */

    /* match with config-override.js on the csr side */
    config.resolve.alias['web_common'] = path.resolve('./src/wc.src');
    config.resolve.alias['app_src'] = path.resolve('./src/app.src');
    config.resolve.alias['rnjs_common'] = path.resolve('./src/js.app');
    //config.resolve.alias.AppStyles$ = path.resolve('./src/app.src/styles/AppStyles')


    //copied from cra config
    //Probably not needed, 
    config.resolve.alias['babel-runtime']=path.dirname(require.resolve('babel-runtime/package.json'));


    /*
     *  add ./src to module resolver so you can import
     *  modules with absolute path
     *  again, this might not be of use to others...
     */
    config.resolve.modules.push('./src');


    let resOfBabelRule=getIdx_RulesByLoader(config.module.rules,
                                            IS_DEV,
                                            IS_WEB,
                                            'babel-loader', //loader name
                                            './testFileNm.js' //test file name for regex
    );



    /* noticed besides my sources, I also had to add react-native-vector-icons
    this was not the only change for RN-vector-icons though, but other changes
    for RN-vector icons are in babel related rules outside of this config file */
    const pathsToMySourcesArr=
      [
        fs.realpathSync(paths.appSrc+'/js.app'),
        fs.realpathSync(paths.appSrc+'/app.src'),
        fs.realpathSync(paths.appSrc+'/wc.src'),
        fs.realpathSync(paths.appNodeModules+'/react-native-vector-icons'),
        fs.realpathSync(paths.appNodeModules+'/react-native-vector-icons/node_modules'),
      ];



    config.module.rules[resOfBabelRule.ruleIdx]
          .include
          .push(...pathsToMySourcesArr);//use spread to push invidiual elements

    //this is a must 
    config.resolve.symlinks=false;

    /* react native vector icons @start<strong i="11">@step</strong>:1 */

    const newRNVectorIconsRule={
      test: /\.ttf$/,
      loader: require.resolve("file-loader"), // or directly file-loader
      include: fs.realpathSync(paths.appNodeModules+'/react-native-vector-icons')
    };

    config.module.rules.push(newRNVectorIconsRule);

    /* react native vector icons @end<strong i="12">@step</strong>:1 */


    if (IS_WEB) {
      if ( !IS_DEV ) {
        config.plugins.push( new BundleAnalyzerPlugin( {
          analyzerMode: "static",
          reportFilename: "webpack-report.html",
          openAnalyzer: false,
        } ) );
      }
    }



    /*
     * I share some of my react components with my
     * react native part of the system
     * So  UsefulComponent.web.js   is for web
     *  UsefulCompoenent.android.js is for android
     * Usefulcomponent.ios.js is for IOS
     *
     * By the way, react's CRA allows for web.js convention
     * so this should probably be a feature of razzle too
     * rather than a customization
     */
    config.resolve.extensions = config.resolve.extensions.concat([
      '.web.js'
    ]);

    return config;

  },
};

لقد تمكنت من تشغيله ، شكرًا على المساعدة. سأقوم بعمل علاقات عامة مع مثال قريبًا.

هل يمكنك تقديم مثال @ MaxGoh

تأخرت قليلاً في هذا الأمر ، ولكن إليك ما نجح معي:

const path = require("path");

module.exports = {
    modify(config, { target, dev }, webpack) {
        for (const rule of config.module.rules) {
            if (rule.test && rule.test.toString() === "/\\.module\\.css$/") {
                const scss = { ...rule };

                scss.test = /\.scss$/;
                scss.include = path.join(__dirname, "src");
                scss.use.push({ loader: "sass-loader" });

                config.module.rules.push(scss);

                break;
            }
        }

        return config;
    }
};
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

dizzyn picture dizzyn  ·  3تعليقات

krazyjakee picture krazyjakee  ·  3تعليقات

GouthamKD picture GouthamKD  ·  3تعليقات

JacopKane picture JacopKane  ·  3تعليقات

gabimor picture gabimor  ·  3تعليقات